It would be great if JSON.parse could support parsing directly into StaticArrays.jl static arrays. For example, it would be nice if the following worked:
julia> using JSON, StaticArrays
julia> JSON.parse("[1,2]", Vector{Int})
2-element Vector{Int64}:
1
2
julia> JSON.parse("[1,2]", SVector{2,Int})
ERROR: MethodError: Cannot `convert` an object of type UndefInitializer to an object of type Int64
The function `convert` exists, but no method is defined for this combination of argument types.
Closest candidates are:
convert(::Type{T}, ::T) where T<:Number
@ Base number.jl:6
convert(::Type{T}, ::Number) where T<:Number
@ Base number.jl:7
convert(::Type{T}, ::T) where T
@ Base Base_compiler.jl:133
...
Stacktrace:
[1] macro expansion
@ ~/.julia/packages/StaticArraysCore/7xxEJ/src/StaticArraysCore.jl:88 [inlined]
[2] convert_ntuple
@ ~/.julia/packages/StaticArraysCore/7xxEJ/src/StaticArraysCore.jl:84 [inlined]
[3] SVector{2, Int64}(x::Tuple{UndefInitializer, Int64})
@ StaticArraysCore ~/.julia/packages/StaticArraysCore/7xxEJ/src/StaticArraysCore.jl:120
[4] StaticArray
@ ~/.julia/packages/StaticArrays/DsPgf/src/convert.jl:173 [inlined]
[5] initialize
@ ~/.julia/packages/StructUtils/CvpPP/src/StructUtils.jl:172 [inlined]
[6] makearray(style::JSON.JSONReadStyle{JSON.Object{String, Any}, Nothing}, ::Type{SVector{2, Int64}}, source::JSON.LazyValue{String})
@ StructUtils ~/.julia/packages/StructUtils/CvpPP/src/StructUtils.jl:873
[7] make(style::JSON.JSONReadStyle{JSON.Object{String, Any}, Nothing}, T::Type, source::JSON.LazyValue{String})
@ StructUtils ~/.julia/packages/StructUtils/CvpPP/src/StructUtils.jl:779
[8] _parse
@ ~/.julia/packages/JSON/0oqO1/src/parse.jl:193 [inlined]
[9] parse(x::JSON.LazyValue{String}, ::Type{SVector{…}}; dicttype::Type{JSON.Object{…}}, null::Nothing, style::JSON.JSONReadStyle{JSON.Object{…}, Nothing})
@ JSON ~/.julia/packages/JSON/0oqO1/src/parse.jl:189
[10] parse
@ ~/.julia/packages/JSON/0oqO1/src/parse.jl:189 [inlined]
[11] parse(buf::String, ::Type{SVector{…}}; dicttype::Type{JSON.Object{…}}, null::Nothing, style::JSON.JSONReadStyle{JSON.Object{…}, Nothing}, kw::@Kwargs{})
@ JSON ~/.julia/packages/JSON/0oqO1/src/parse.jl:181
[12] parse(buf::String, ::Type{SVector{2, Int64}})
@ JSON ~/.julia/packages/JSON/0oqO1/src/parse.jl:181
[13] top-level scope
@ REPL[3]:1
Some type information was truncated. Use `show(err)` to see complete types.
I found that defining the following method makes it work:
julia> StructUtils.makearray(style, T::Type{<:StaticVector}, source) = T([source[i][] for i in 1:length(T)]), StructUtils.applyeach(style, StructUtils.ArrayClosure(eltype(T)[], style), source)
julia> JSON.parse("[1,2]", SVector{2,Int})
2-element SVector{2, Int64} with indices SOneTo(2):
1
2
However, I’m not sure which function would be the appropriate extension point for this. It’s also unclear to me which package should provide this support — JSON.jl, StaticArrays.jl, or possibly even StructUtils.jl. In any case, this would likely need to be implemented as a package extension. Since StructUtils.makearray does not appear to be documented, I’m not sure whether it is considered internal API.
It would be great if
JSON.parsecould support parsing directly into StaticArrays.jl static arrays. For example, it would be nice if the following worked:I found that defining the following method makes it work:
However, I’m not sure which function would be the appropriate extension point for this. It’s also unclear to me which package should provide this support — JSON.jl, StaticArrays.jl, or possibly even StructUtils.jl. In any case, this would likely need to be implemented as a package extension. Since
StructUtils.makearraydoes not appear to be documented, I’m not sure whether it is considered internal API.