How to read tuples with JSON3?

I am new to JSON3.jl and trying to do the following

julia> using JSON3

julia> tup = (:car,"Mercedes","S500",5,250.1)
(:car, "Mercedes", "S500", 5, 250.1)

julia> json = JSON3.write(tup)
"[\"car\",\"Mercedes\",\"S500\",5,250.1]"

I know I can do this:

d = JSON3.read(json,Tuple{Symbol,String,String,Int64,Float64})
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Symbol

But I get an error reading the object of type symbol

I think the reason is that to get Symbol from String one needs Meta.parse instead of convert. So it could be a bug somewhere.

For the time being you could add the conversion:

using JSON3
Base.convert(::Type{Symbol}, s::String) = Meta.parse(s)

then

julia> JSON3.read(tupjson, tuptype)
(:car, "Mercedes", "S500", 5, 250.1)

julia> tup = (:car,"Mercedes","S500",5,250.1)
(:car, "Mercedes", "S500", 5, 250.1)

julia> tuptype = typeof(tup)
Tuple{Symbol,String,String,Int64,Float64}

julia> tupjson = JSON3.write(tup)
"[\"car\",\"Mercedes\",\"S500\",5,250.1]"

julia> JSON3.read(tupjson, tuptype)
(:car, "Mercedes", "S500", 5, 250.1)
2 Likes

I raised this issue https://github.com/quinnj/JSON3.jl/issues/28

2 Likes

This is mainly because JSON3 doesn’t have specialized support for Tuples yet. It supports them via a general “array” interface, but the general array interface assumes the container will have a single eltype when reading. In this case, your tuple type is not homogenous, so each element is just parsed generally, then it tries to convert at the end, as opposed to using the types of each element of your tuple and parsing the types specifically. I don’t think it’d be too hard to add support for this though, since tuples can be a really useful way to bundle a couple things together.

5 Likes

Just FYI, just merged support for reading heterogenously-typed tuples in JSON3.jl: https://github.com/quinnj/JSON3.jl/pull/29.

5 Likes

@quinnj Now it’s works, thank you so much for your help.

julia> JSON3.read("[\"car\",\"Mercedes\"]", Tuple{Symbol, String})
(:car, "Mercedes")

But another problem arose. I am trying to read a tuple in a struct

struct data
    t :: Tuple{Symbol, String}
end

Getting this error when I run test

julia> JSON3.StructType(::Type{data}) = JSON3.Struct()

julia> JSON3.read("{\"t\":[\"car\",\"Mercedes\"]}", data)
ERROR: ArgumentError: invalid JSON at byte position 23 while parsing type Tuple{Symbol,String}: ExpectedComma
{"t":["car","Mercedes"]}

Hey @Elmer_Cusipuma, sorry for the slow response, I’m trying to catch up on recent pings/issues. There was a bug in the recent tuple support I added to JSON3.jl, so I just pushed a fix and made a new release, so once that’s merged in the registry, this should work as expected.

Sorry for the hassle.

3 Likes

Thanks!