diff --git a/src/lazy.jl b/src/lazy.jl index a4548d2..ff943f1 100644 --- a/src/lazy.jl +++ b/src/lazy.jl @@ -234,7 +234,7 @@ _applyobject(f::F, x) where {F} = applyobject(f, x) end while true # applystring returns key as a PtrString - key, pos = applystring(nothing, LazyValue(buf, pos, JSONTypes.STRING, getopts(x))) + key, pos = applystring(nothing, LazyValue(buf, pos, JSONTypes.STRING, getopts(x), false)) @nextbyte if b != UInt8(':') error = ExpectedColon diff --git a/src/materialize.jl b/src/materialize.jl index 0c350f5..f3be941 100644 --- a/src/materialize.jl +++ b/src/materialize.jl @@ -259,9 +259,9 @@ end return pos elseif mutable(T) y = T() - pos = materialize!(x, y, style, O) + cont = materialize!(x, y, style, O) valfunc(y) - return pos + return cont.pos elseif kwdef(T) kws = Pair{Symbol, Any}[] c = KwClosure{JS, T, O}(style, kws) @@ -307,9 +307,9 @@ end # and the default constructor is used with positional arguments from the json array if mutable(T) y = T() - pos = materialize!(x, y, style, O) + cont = materialize!(x, y, style, O) valfunc(y) - return pos + return cont.pos elseif kwdef(T) kws = Pair{Symbol, Any}[] c = KwIndexClosure{JS, T, O}(style, kws) @@ -321,7 +321,8 @@ end A = Vector{Any} a = initarray(A) pos = applyarray(GenericArrayClosure{JS, A, O}(style, a), x).pos - valfunc(T(a...)) + constructor = T <: Tuple ? tuple : T <: NamedTuple ? ((x...) -> T(tuple(x...))) : T + valfunc(constructor(a...)) return pos end end @@ -497,16 +498,16 @@ function materialize!(x::Values, y::T, style::JSONStyle=DefaultStyle(), dicttype if type == JSONTypes.OBJECT if dictlike(T) goc = GenericObjectClosure{JS, T, O}(style, y) - return applyobject(goc, x).pos + return applyobject(goc, x) else mc = MutableClosure{JS, T, O}(style, y) - return applyobject(mc, x).pos + return applyobject(mc, x) end elseif type == JSONTypes.ARRAY # the JSON source is an array, so we're going to # apply each element to `y` in order, assuming each array element is the right field # for y in corresponding field index order - return applyarray(MutableIndexClosure{JS, T, O}(style, y), x).pos + return applyarray(MutableIndexClosure{JS, T, O}(style, y), x) else throw(ArgumentError("cannot materialize! from a non-object/array JSON instance")) end diff --git a/test/runtests.jl b/test/runtests.jl index e4d79c0..4dbdcdd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -40,7 +40,7 @@ end @test isempty(x) && typeof(x) == Dict{String, Any} x = JSONBase.materialize("{}") @test isempty(x) && typeof(x) == Dict{String, Any} - @test_throws ArgumentError JSONBase.materialize(JSONBase.LazyValue(".", 1, JSONBase.JSONTypes.OBJECT, JSONBase.OPTIONS)) + @test_throws ArgumentError JSONBase.materialize(JSONBase.LazyValue(".", 1, JSONBase.JSONTypes.OBJECT, JSONBase.OPTIONS, true)) x = JSONBase.lazy("1") @test_throws ArgumentError JSONBase.API.applyeach((k, v) -> nothing, x) x = JSONBase.materialize("{\"a\": 1}") diff --git a/test/struct.jl b/test/struct.jl index 9dc0402..14f580d 100644 --- a/test/struct.jl +++ b/test/struct.jl @@ -235,6 +235,12 @@ end # materialize kwdef from json array obj = JSONBase.materialize("""[1, 3.14, "hey there sailor"]""", F) @test obj == F(1, 3.14, "hey there sailor") + # materialize NamedTuple from json array + obj = JSONBase.materialize("""[1, 3.14, "hey there sailor"]""", NamedTuple{(:id, :rate, :name), Tuple{Int, Float64, String}}) + @test obj == (id = 1, rate = 3.14, name = "hey there sailor") + # materialize Tuple from json array + obj = JSONBase.materialize("""[1, 3.14, "hey there sailor"]""", Tuple{Int, Float64, String}) + @test obj == (1, 3.14, "hey there sailor") obj = JSONBase.materialize("""{ "a": 1,"b": 2.0,"c": "3"}""", D) @test obj == D(1, 2.0, "3") obj = JSONBase.materialize("""{ "x1": "1","x2": "2","x3": "3","x4": "4","x5": "5","x6": "6","x7": "7","x8": "8","x9": "9","x10": "10","x11": "11","x12": "12","x13": "13","x14": "14","x15": "15","x16": "16","x17": "17","x18": "18","x19": "19","x20": "20","x21": "21","x22": "22","x23": "23","x24": "24","x25": "25","x26": "26","x27": "27","x28": "28","x29": "29","x30": "30","x31": "31","x32": "32","x33": "33","x34": "34","x35": "35"}""", LotsOfFields)