Skip to content

Commit

Permalink
Add extra keyword argument for ignoring extra fields (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
simsurace authored Dec 17, 2024
1 parent 02e2ecf commit ce90511
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/JSON3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ invalid JSON at byte position $pos while parsing type $T: $error
$(String(buf[max(1, pos-25):min(end, pos+25)]))
"""))

@enum Error UnexpectedEOF ExpectedOpeningObjectChar ExpectedOpeningQuoteChar ExpectedOpeningArrayChar ExpectedClosingArrayChar ExpectedComma ExpectedSemiColon ExpectedNewline InvalidChar InvalidNumber
@enum Error UnexpectedEOF ExpectedOpeningObjectChar ExpectedOpeningQuoteChar ExpectedOpeningArrayChar ExpectedClosingArrayChar ExpectedComma ExpectedSemiColon ExpectedNewline InvalidChar InvalidNumber ExtraField

# AbstractDict interface
Base.length(obj::Object) = getnontypemask(gettape(obj)[2])
Expand Down
1 change: 1 addition & 0 deletions src/read.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Read JSON.
* `dateformat`: A [`DateFormat`](https://docs.julialang.org/en/v1/stdlib/Dates/#Dates.DateFormat) describing the format of dates in the JSON so that they can be read into `Date`s, `Time`s, or `DateTime`s when reading into a type. [default `Dates.default_format(T)`]
* `parsequoted`: Accept quoted values when reading into a NumberType. [default `false`]
* `numbertype`: Type to parse numbers as. [default `nothing`, which parses numbers as Int if possible, Float64 otherwise]
* `ignore_extra_fields`: Ignore extra fields in the JSON when reading into a struct. [default `true`]
"""
function read(json::AbstractString; jsonlines::Bool=false,
numbertype::Union{DataType, Nothing}=nothing, kw...)
Expand Down
9 changes: 7 additions & 2 deletions src/structs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ end
return
end

function read(::Struct, buf, pos, len, b, ::Type{T}; kw...) where {T}
function read(::Struct, buf, pos, len, b, ::Type{T}; ignore_extra_fields::Bool=true, kw...) where {T}
values = Vector{Any}(undef, fieldcount(T))
if b != UInt8('{')
error = ExpectedOpeningObjectChar
Expand Down Expand Up @@ -612,7 +612,12 @@ function read(::Struct, buf, pos, len, b, ::Type{T}; kw...) where {T}
if StructTypes.applyfield(c, T, key)
pos = c.pos
else
pos, _ = read(Struct(), buf, pos, len, b, Any)
if ignore_extra_fields
pos, _ = read(Struct(), buf, pos, len, b, Any)
else
error = ExtraField
@goto invalid
end
end
@eof
b = getbyte(buf, pos)
Expand Down
8 changes: 8 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1109,4 +1109,12 @@ y[1] = x
@testset "Arrow" include("arrow.jl")
end

# https://github.com/quinnj/JSON3.jl/issues/296
struct TypeWithoutExtraField
a::Int
end
string_with_extra_field = "{\"a\": 1, \"b\": 2}"
@test JSON3.read(string_with_extra_field, TypeWithoutExtraField) == TypeWithoutExtraField(1)
@test_throws ArgumentError JSON3.read(string_with_extra_field, TypeWithoutExtraField, ignore_extra_fields=false)

end # @testset "JSON3"

0 comments on commit ce90511

Please sign in to comment.