I’m using JSON3.jl in a project and I found this unexpected behavior when reading Dict{Tuple{Int,Int}, T}.
I don’t know if I’m doing something wrong or if there is just a bug in the package but this is a quite classic operation so I thought it would work straight away.
Here is a simple example that reproduces the bug :
using StructTypes, JSON3
struct A
a::Dict{Tuple{Int,Int}, Char}
end
StructTypes.StructType(::Type{A}) = StructTypes.Struct()
a = A(Dict((1, 2) => 'a', (2, 4) => 'b', (15, 20) => 'c'))
@show JSON3.read(JSON3.write(a), A)
The write operation works well. You get this JSON:
function parsetuple(s::AbstractString)
r = match(r"\(([0-9]+), *([0-9]+)\)", s)
return (parse(Int, r.captures[1]), parse(Int, r.captures[2]))
end
StructTypes.StructType(::Type{Tuple{Int,Int}}) = StructTypes.StringType()
StructTypes.construct(::Type{Tuple{Int,Int}}, x::String; kw...) = parsetuple(x)
trick if you’re using JSON3 just for debugging purposes.
It should no go in prod as StructTypes.StructType(::Type{Tuple{Int,Int}}) is already defined and returns ArrayType().
or define a new constructor and convert the string keys into the desired type.
I think the main problem is that JSON keys must be strings, so it is writing (1,2) as a string "(1,2)" to use as the key, which does not preserve the actual meaning of the tuple.