If `StructTypes.subtypes` has length one, then we shouldn't need a subtype key
DilumAluthge opened this issue · comments
Dilum Aluthge commented
If we have an abstract type, and we have only defined one concrete subtype (i.e. StructTypes.subtypes
has length one), then JSON3 should automatically pick this subtype, whether or not StructTypes.subtypekey
has been defined.
Here is an example. We have Vehicle
, which we declare as StructTypes.StructType(::Type{Vehicle}) = StructTypes.AbstractType()
. Then we only declare a single subtype: StructTypes.subtypes(::Type{Vehicle}) = (Car=Car,)
. So JSON3 should always read Vehicle
s in as Car
s.
julia> import JSON3, StructTypes
julia> abstract type Vehicle end
julia> mutable struct Car <: Vehicle
topSpeed::Float64
model::String
make::String
seatingCapacity::Int
Car() = new()
end
julia> StructTypes.StructType(::Type{Vehicle}) = StructTypes.AbstractType()
julia> StructTypes.StructType(::Type{Car}) = StructTypes.Mutable()
julia> StructTypes.subtypes(::Type{Vehicle}) = (Car=Car,)
julia> j = """
{
"make": "Mercedes-Benz",
"model": "S500",
"seatingCapacity": 5,
"topSpeed": 250.1
}
"""
"{\n \"make\": \"Mercedes-Benz\",\n \"model\": \"S500\",\n \"seatingCapacity\": 5,\n \"topSpeed\": 250.1\n}\n"
julia> car = JSON3.read(j, Vehicle)
ERROR: ArgumentError: invalid json abstract type: didn't find subtypekey
Stacktrace:
[1] #read#41
@ ~/.julia/packages/JSON3/LtYDK/src/structs.jl:617 [inlined]
[2] read
@ ~/.julia/packages/JSON3/LtYDK/src/structs.jl:555 [inlined]
[3] read(str::String, ::Type{Vehicle}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ JSON3 ~/.julia/packages/JSON3/LtYDK/src/structs.jl:34
[4] read(str::String, ::Type{Vehicle})
@ JSON3 ~/.julia/packages/JSON3/LtYDK/src/structs.jl:33
[5] top-level scope
@ REPL[8]:1
Dilum Aluthge commented
Fixed by #97