There’s no parsequoted keyword argument in JSON.jl 1.0 — but you can get the capability yourself, via a custom style instead of a keyword argument:
using JSON
struct MyType
x::Float64
end
struct QuotedNumbers <: JSON.JSONStyle end
JSON.lift(::QuotedNumbers, ::Type{T}, x::AbstractString) where {T<:Real} = parse(T, x)
JSON.parse("{\"x\":\"4.0\"}", MyType; style=QuotedNumbers()) # MyType(4.0)
The style applies everywhere in the document, so it handles the nested cases too — struct fields, Vector{Float64}, Dict values, Union{Float64, Nothing} fields, and top-level scalars. String fields are unaffected, and null still comes through as nothing:
struct Inner; y::Int; end
struct Outer; a::Float64; b::Inner; c::Vector{Float64}; d::Union{Float64,Nothing}; e::String; end
JSON.parse("""{"a":"1.5","b":{"y":"7"},"c":["1","2.5"],"d":null,"e":"hello"}""",
Outer; style=QuotedNumbers())
# Outer(1.5, Inner(7), [1.0, 2.5], nothing, "hello")
One thing this gets you that parsequoted never did: add the matching lower and the numbers round-trip back out quoted, instead of silently becoming unquoted on write.
JSON.lower(::QuotedNumbers, x::Real) = string(x)
v = JSON.parse("{\"x\":\"4.0\"}", MyType; style=QuotedNumbers())
JSON.json(v; style=QuotedNumbers()) # {"x":"4.0"}
JSON.json(v) # {"x":4.0} (default style, unchanged)
If only one field is quoted rather than the whole document, you can skip the style entirely and put a lift on that field (using StructUtils @tags macro and the “field tag” syntax starting with &):
@tags struct Mixed
x::Float64 &(lift = v -> v isa AbstractString ? parse(Float64, v) : Float64(v),)
y::Float64
end
JSON.parse("{\"x\":\"4.0\",\"y\":5.0}", Mixed) # Mixed(4.0, 5.0)
A caveat worth knowing: you now own the corner cases, because parse(T, x) decides them. In particular "" will throw rather than give you nothing, and "7.0" into an Int field will throw. Both are easy to handle in the lift body if your source does that — which is honestly an improvement over JSON3, where a couple of those cases escaped as a bare AssertionError: b == UInt8('"').