diff --git a/src/gentypes.jl b/src/gentypes.jl index 3ca9bad..1943c27 100644 --- a/src/gentypes.jl +++ b/src/gentypes.jl @@ -324,7 +324,7 @@ If `mutable` is `true`, an empty constructor is included in the struct definitio """ function generate_exprs(t; root_name::Symbol = :Root, mutable = true) exprs = [] - generate_expr!(exprs, t, root_name; mutable = mutable) + generate_expr!(exprs, t, root_name; mutable = mutable, is_root = true) return exprs end @@ -334,12 +334,12 @@ function generate_expr!( nt::Type{NamedTuple{N,T}}, root_name::Symbol; mutable::Bool = true, + kwargs..., ) where {N,T<:Tuple} sub_exprs = [] for (n, t) in zip(N, fieldtypes(nt)) push!(sub_exprs, generate_field_expr!(exprs, t, n; mutable = mutable)) end - struct_name = pascalcase(root_name) struct_exprs = filter(e -> e.head == :struct && e.args[2] == struct_name, exprs) if length(struct_exprs) > 0 # already a struct with this name, augment it @@ -357,14 +357,20 @@ function generate_expr!( return struct_name end -# should only hit this in the case of the array being the root of the type +# If at the root of a JSON expression, use the vectors type as the type, otherwise, generate +# with the vector still wrapping the type function generate_expr!( exprs, ::Type{Base.Array{T,N}}, root_name::Symbol; + is_root::Bool = false, kwargs..., ) where {T<:NamedTuple,N} - return generate_expr!(exprs, T, root_name; kwargs...) + if is_root + return generate_expr!(exprs, T, root_name; kwargs...) + else + return Expr(:curly, :Array, generate_expr!(exprs, T, root_name; kwargs...), 1) + end end function generate_expr!(exprs, t::Type{T}, root_name::Symbol; kwargs...) where {T} diff --git a/test/gentypes.jl b/test/gentypes.jl index 8801dc1..967293f 100644 --- a/test/gentypes.jl +++ b/test/gentypes.jl @@ -294,6 +294,41 @@ parsed = JSON3.read(weird_jsons[3], JSONTypes.Root) @test parsed.x == 7 @test !isdefined(parsed, :a) + + # Issue #209 + daily_menu = """{ + "object":"page", + "date":"23.03.2022" + }""" + dishes = """{ + "object":"list", + "results":[ + { + "object":"dish", + "name":"Spaghetti" + } + ] + }""" + + JSON3.@generatetypes [daily_menu, dishes] + + new_daily_menu = """{ + "object":"page", + "date":"24.03.2022" + }""" + new_dishes = """{ + "object":"list", + "results":[ + { + "object":"dish", + "name":"Pizza" + } + ] + }""" + + menu_struct = JSON3.read(new_daily_menu, JSONTypes.Root) + dishes_struct = JSON3.read(new_dishes, JSONTypes.Root) + @test dishes_struct.results[1].object == "dish" end @testset "Raw Types" begin