@@ -174,9 +174,12 @@ StructUtils.fieldtagkey(::JSONStyle) = :json
174174StructUtils. defaultstate (st:: JSONReadStyle ) = StructUtils. defaultstate (st. style)
175175
176176# forward StructUtils API to the inner style so user-provided JSONStyle dispatches are honored
177- StructUtils. dictlike (st:: JSONReadStyle , :: Type{T} ) where {T} = StructUtils. dictlike (st. style, T)
178- StructUtils. arraylike (st:: JSONReadStyle , :: Type{T} ) where {T} = StructUtils. arraylike (st. style, T)
179- StructUtils. nulllike (st:: JSONReadStyle , :: Type{T} ) where {T} = StructUtils. nulllike (st. style, T)
177+ StructUtils. dictlike (st:: JSONReadStyle{O,N,S} , :: Type{T} ) where {O,N,S<: JSONStyle ,T} =
178+ StructUtils. dictlike (st. style, T)
179+ StructUtils. arraylike (st:: JSONReadStyle{O,N,S} , :: Type{T} ) where {O,N,S<: JSONStyle ,T} =
180+ StructUtils. arraylike (st. style, T)
181+ StructUtils. nulllike (st:: JSONReadStyle{O,N,S} , :: Type{T} ) where {O,N,S<: JSONStyle ,T} =
182+ StructUtils. nulllike (st. style, T)
180183# Keep structlike forwarding specific to custom JSONStyle wrappers so type-level StructStyle
181184# specializations (for example @nonstruct types) continue to dispatch without ambiguity.
182185StructUtils. structlike (st:: JSONReadStyle{O,N,S} , :: Type{T} ) where {O,N,S<: JSONStyle ,T} =
@@ -192,6 +195,11 @@ function jsonreadstyle(::Type{T}, ::Type{O}, null, style::StructStyle, unknown_f
192195 if T === Any && ! ignore_unknown_fields
193196 throw (ArgumentError (" `unknown_fields` is only supported when parsing into a target type or existing object" ))
194197 end
198+ # A JSONStyle already has JSON field tags and lazy-value lifting; avoid wrapping
199+ # the default path so broad style methods do not become ambiguous.
200+ if O === DEFAULT_OBJECT_TYPE && null === nothing && ignore_unknown_fields && style isa JSONStyle
201+ return style
202+ end
195203 return JSONReadStyle {O} (null, style, ignore_unknown_fields)
196204end
197205
@@ -377,28 +385,47 @@ function StructUtils.make(st::StructStyle, ::Type{Any}, x::LazyValues)
377385end
378386
379387# catch PtrString via lift or make! so we can ensure it never "escapes" to user-level
388+ StructUtils. liftkey (st:: JSONStyle , :: Type{T} , x:: PtrString ) where {T} =
389+ StructUtils. liftkey (st, T, convert (String, x))
380390StructUtils. liftkey (st:: JSONReadStyle , :: Type{T} , x:: PtrString ) where {T} =
381391 StructUtils. liftkey (st, T, convert (String, x))
392+ StructUtils. lift (st:: JSONStyle , :: Type{T} , x:: PtrString , tags) where {T} =
393+ StructUtils. lift (st, T, convert (String, x), tags)
382394StructUtils. lift (st:: JSONReadStyle , :: Type{T} , x:: PtrString , tags) where {T} =
383395 StructUtils. lift (st, T, convert (String, x), tags)
396+ StructUtils. lift (st:: JSONStyle , :: Type{T} , x:: PtrString ) where {T} =
397+ StructUtils. lift (st, T, convert (String, x))
384398StructUtils. lift (st:: JSONReadStyle , :: Type{T} , x:: PtrString ) where {T} =
385399 StructUtils. lift (st, T, convert (String, x))
386400
387401# liftkey for numeric dict key types to enable round-tripping Dict{Int,V}, Dict{Float64,V}, etc.
388402# these correspond to the lowerkey definitions in write.jl that convert numeric keys to strings
389- StructUtils. liftkey (:: JSONReadStyle , :: Type{T} , x:: AbstractString ) where {T<: Integer } = Base. parse (T, x)
390- StructUtils. liftkey (:: JSONReadStyle , :: Type{T} , x:: AbstractString ) where {T<: AbstractFloat } = Base. parse (T, x)
403+ StructUtils. liftkey (:: JSONStyle , :: Type{T} , x:: AbstractString ) where {T<: Integer } = Base. parse (T, x)
404+ StructUtils. liftkey (:: JSONStyle , :: Type{T} , x:: AbstractString ) where {T<: AbstractFloat } = Base. parse (T, x)
391405
392406StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x, tags) where {T} = StructUtils. lift (style. style, T, x, tags)
393407StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x) where {T} = StructUtils. lift (style. style, T, x)
394408
409+ function StructUtils. lift (style:: JSONStyle , :: Type{T} , x:: LazyValues ) where {T<: AbstractArray{E,0} } where {E}
410+ m = T (undef)
411+ m[1 ], pos = StructUtils. lift (style, E, x)
412+ return m, pos
413+ end
414+
395415function StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x:: LazyValues ) where {T<: AbstractArray{E,0} } where {E}
396416 m = T (undef)
397417 m[1 ], pos = StructUtils. lift (style, E, x)
398418 return m, pos
399419end
400420
401- function StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x:: LazyValues , tags= (;)) where {T}
421+ StructUtils. lift (style:: JSONStyle , :: Type{T} , x:: LazyValues , tags= (;)) where {T} =
422+ _liftjsonvalue (style, T, x, tags)
423+ StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x:: LazyValues , tags) where {T} =
424+ _liftjsonvalue (style, T, x, tags)
425+ StructUtils. lift (style:: JSONReadStyle , :: Type{T} , x:: LazyValues ) where {T} =
426+ _liftjsonvalue (style, T, x, (;))
427+
428+ function _liftjsonvalue (style:: JSONStyle , :: Type{T} , x:: LazyValues , tags) where {T}
402429 type = gettype (x)
403430 buf = getbuf (x)
404431 if type == JSONTypes. STRING
0 commit comments