JSON3.jl struct read

using JSON3

struct Foo
    foo::Int
    bar::String
end

JSON3.StructTypes.StructType(::Type{Foo}) = JSON3.StructTypes.Struct()

obj = Foo(1, "bar")

If if just have the pure struct it works fine:

julia> json = JSON3.write(obj)
"{\"foo\":1,\"bar\":\"bar\"}"

julia> JSON3.read(json, Foo)
Foo(1, "bar")

How can i construct the type if it is just a field of a dict?

julia> json = JSON3.write(Dict("a" => 1, "b" => obj))
"{\"b\":{\"foo\":1,\"bar\":\"bar\"},\"a\":1}"

julia> JSON3.read(json)
JSON3.Object{Base.CodeUnits{UInt8, String}, Vector{UInt64}} with 2 entries:
  :b => {…
  :a => 1

This can’t be it:

julia> JSON3.read(JSON3.write(JSON3.read(json)["b"]), Foo)
Foo(1, "bar")

I can think of two options;

  1. You could define a quick wrapper struct:
mutable struct Wrapper
    b::Foo
    Wrapper() = new()
end
StructTypes.StructType(::Type{Wrapper}) = StructTypes.Mutable()

JSON3.read(json, Wrapper)
  1. The StructTypes.jl package has a utility function called StructTypes.constructfrom(T, obj), that could be used in your case like:
foo = StructTypes.constructfrom(Foo, JSON3.read(json)["b"])

Basically, it allows using the StructType information for T to extract the properties from any AbstractDict provided, which JSON3.Object satisfies.