quinnj / JSON3.jl

Other
214 stars 47 forks source link

Struct as an array wrapper #158

Closed EricForgy closed 3 years ago

EricForgy commented 3 years ago
Julia v1.5.4
JSON3 v1.8.1
Windows

Hi 👋

Apologies if this is covered elsewhere, but wanted to leave a quick note:

struct MyStruct{T,K,N} <: AbstractArray{K,N}
    a::T
    b::Array{K,N}
end

Base.size(m::MyStruct) = size(m.b)

Base.getindex(m::MyStruct,I...) = getindex(m.b,I...)

StructTypes.StructType(::Type{MyStruct}) = StructTypes.Struct()

With above, I'm getting:

julia> m = MyStruct(1,[1,2,3]);

julia> JSON3.write(m)
"[1,2,3]"

I expect

"{"a":1,"b":[1,2,3]}" 

What am I missing?

quinnj commented 3 years ago

Because you subtype AbstractArray, your type will naturally be treated "array-like". It seems you're trying to override this by defining StructTypes.StructType, but the issue there is you're defining it specifically on the abstract type MyStruct, whereas the call of JSON3.write will end up being something like StructTypes.StructType(MyStruct{Int, Int, 1}). So in order to catch "all" the parameterizations of your struct, you'd want something like StructTypes.StructType(::Type{<:MyStruct}) = StructTypes.Struct()

EricForgy commented 3 years ago

That did the trick. Thank you @quinnj 🙌

I was pulling my hair out, but I needed the <: 🤦