quinnj / JSON3.jl

Other
214 stars 47 forks source link

Add partially typed objects #265

Open danlooo opened 1 year ago

danlooo commented 1 year ago

Often, we are interested in only a part of the JSON object. We want to write the types only for the relevant sections. Let there be an object with a relevant element a and a complex element b that we do not want to write out the complex type. We won't use b downstream much, but we want to still have consistent access. Automatically generated types might be overwhelming.

We can just use the Type Any for that:

using JSON3

json_string = """
{
    "a" : 1,
    "b" : {
        "x" : 2,
        "y": "foo"
    }
}
"""

struct TypeA
    a::Number
    b::Any
end

obj1 = JSON3.read(json_string, TypeA)
obj1.b.y # ERROR: type Dict has no field y, but consistent syntax
obj1.b["y"] # "foo", works but inconsistent syntax

This will give us element b of type Dict{String, Any}. However, we can not use the . operator to get the field here like we can do it on the parsed sections. This is inconsistent. Therefore we might want to use JSON3.Object instead of Any. A quick fix would be:

struct TypeB
    a::Number
    b::JSON3.Object
end

# Fix
function JSON3.Object(d::Dict{Symbol,Any})
    JSON3.read(JSON3.write(d))
end

obj2 = JSON3.read(json_string, TypeB)
obj2.b.y # foo

Shall this feature be part of JSON3.jl? Is there a better way to solve the partial explicit typing?