1- # JSONWrapper for OpenAPI models handles
2- # - null fields
3- # - field names that are Julia keywords
4- struct JSONWrapper{T<: APIModel } <: AbstractDict{Symbol, Any}
5- wrapped:: T
6- flds:: Tuple
7- end
1+ # Declare how StructTypes should handle APIModels
2+ StructTypes. StructType (:: Type{<:APIModel} ) = StructTypes. Struct ()
83
9- JSONWrapper (o:: T ) where {T<: APIModel } = JSONWrapper (o, filter (n-> hasproperty (o,n) && (getproperty (o,n) != = nothing ), propertynames (o)))
4+ # This single line replaces the entire JSONWrapper implementation.
5+ # It tells JSON.jl to automatically omit fields whose values are `nothing`.
6+ StructTypes. omitempties (:: Type{<:APIModel} ) = true
107
11- getindex (w:: JSONWrapper , s:: Symbol ) = getproperty (w. wrapped, s)
12- keys (w:: JSONWrapper ) = w. flds
13- length (w:: JSONWrapper ) = length (w. flds)
8+ # This hook tells JSON.read to use our custom `from_json` logic
9+ # for constructing APIModel types. This preserves our handling of dates,
10+ # discriminated unions, and other special cases.
11+ StructTypes. construct (:: Type{T} , dict:: Dict ) where {T <: APIModel } = from_json (T, dict)
1412
15- function iterate (w:: JSONWrapper , state... )
16- result = iterate (w. flds, state... )
17- if result === nothing
18- return result
19- else
20- name,nextstate = result
21- val = getproperty (w. wrapped, name)
22- return (name=> val, nextstate)
23- end
24- end
2513
26- lower (o:: T ) where {T<: APIModel } = JSONWrapper (o)
14+ # The `lower` method for UnionAPIModel is still useful because it allows us to
15+ # serialize the inner .value of a oneOf/anyOf type, not the wrapper itself.
16+ # JSON.jl v1.0 still respects `lower`.
17+
2718function lower (o:: T ) where {T<: UnionAPIModel }
2819 if typeof (o. value) <: APIModel
29- return JSONWrapper (o. value)
20+ # Use JSON.lower on the wrapped value to apply its own rules
21+ return JSON. lower (o. value)
3022 elseif typeof (o. value) <: Union{String,Real}
3123 return o. value
3224 else
5951to_json (o) = JSON. json (o)
6052
6153from_json (:: Type{Union{Nothing,T}} , json:: Dict{String,Any} ; stylectx= nothing ) where {T} = from_json (T, json; stylectx)
54+ from_json (:: Type{Union{Nothing,T}} , json:: JSON.Object{String, Any} ; stylectx= nothing ) where {T} = from_json (T, json; stylectx)
55+
6256from_json (:: Type{T} , json:: Dict{String,Any} ; stylectx= nothing ) where {T} = from_json (T (), json; stylectx)
57+ from_json (:: Type{T} , json:: JSON.Object{String, Any} ; stylectx= nothing ) where {T} = from_json (T (), json; stylectx)
58+
6359from_json (:: Type{T} , json:: Dict{String,Any} ; stylectx= nothing ) where {T <: Dict } = convert (T, json)
60+ from_json (:: Type{T} , json:: JSON.Object{String, Any} ; stylectx= nothing ) where {T <: Dict } = convert (T, json)
61+
6462from_json (:: Type{T} , j:: Dict{String,Any} ; stylectx= nothing ) where {T <: String } = to_json (j)
63+ from_json (:: Type{T} , j:: JSON.Object{String, Any} ; stylectx= nothing ) where {T <: String } = to_json (j)
64+
6565from_json (:: Type{Any} , j:: Dict{String,Any} ; stylectx= nothing ) = j
66+ from_json (:: Type{Any} , j:: JSON.Object{String, Any} ; stylectx= nothing ) = j
67+
6668from_json (:: Type{Vector{T}} , j:: Vector{Any} ; stylectx= nothing ) where {T} = j
6769
6870function from_json (:: Type{Vector{T}} , json:: Dict{String, Any} ; stylectx= nothing ) where {T}
@@ -78,10 +80,27 @@ function from_json(::Type{Vector{T}}, json::Dict{String, Any}; stylectx=nothing)
7880 end
7981end
8082
83+ function from_json (:: Type{Vector{T}} , json:: JSON.Object{String, Any} ; stylectx= nothing ) where {T}
84+ if ! isnothing (stylectx) && is_deep_explode (stylectx)
85+ cvt = deep_object_to_array (json)
86+ if isa (cvt, Vector)
87+ return from_json (Vector{T}, cvt; stylectx)
88+ else
89+ return from_json (T, json; stylectx)
90+ end
91+ else
92+ return from_json (T, json; stylectx)
93+ end
94+ end
95+
8196function from_json (o:: T , json:: Dict{String,Any} ;stylectx= nothing ) where {T <: UnionAPIModel }
8297 return from_json (o, :value , json;stylectx)
8398end
8499
100+ function from_json (o:: T , json:: JSON.Object{String, Any} ;stylectx= nothing ) where {T <: UnionAPIModel }
101+ return from_json (o, :value , json;stylectx)
102+ end
103+
85104from_json (:: Type{T} , val:: Union{String,Real} ;stylectx= nothing ) where {T <: UnionAPIModel } = T (val)
86105function from_json (o:: T , val:: Union{String,Real} ;stylectx= nothing ) where {T <: UnionAPIModel }
87106 o. value = val
@@ -96,13 +115,28 @@ function from_json(o::T, json::Dict{String,Any};stylectx=nothing) where {T <: AP
96115 return o
97116end
98117
118+ function from_json (o:: T , json:: JSON.Object{String, Any} ;stylectx= nothing ) where {T <: APIModel }
119+ jsonkeys = [Symbol (k) for k in collect (keys (json))]
120+ for name in intersect (propertynames (o), jsonkeys)
121+ from_json (o, name, json[String (name)];stylectx)
122+ end
123+ return o
124+ end
125+
99126function from_json (o:: T , name:: Symbol , json:: Dict{String,Any} ;stylectx= nothing ) where {T <: APIModel }
100127 ftype = (T <: UnionAPIModel ) ? property_type (T, name, json) : property_type (T, name)
101128 fval = from_json (ftype, json; stylectx)
102129 setfield! (o, name, convert (ftype, fval))
103130 return o
104131end
105132
133+ function from_json (o:: T , name:: Symbol , json:: JSON.Object{String, Any} ;stylectx= nothing ) where {T <: APIModel }
134+ ftype = (T <: UnionAPIModel ) ? property_type (T, name, json) : property_type (T, name)
135+ fval = from_json (ftype, json; stylectx)
136+ setfield! (o, name, convert (ftype, fval))
137+ return o
138+ end
139+
106140function from_json (o:: T , name:: Symbol , v; stylectx= nothing ) where {T <: APIModel }
107141 ftype = (T <: UnionAPIModel ) ? property_type (T, name, Dict {String,Any} ()) : property_type (T, name)
108142 atype = isa (ftype, Union) ? ((ftype. a === Nothing) ? ftype. b : ftype. a) : ftype
0 commit comments