Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extra keyword argument for ignoring extra fields #300

Merged
merged 1 commit into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Loading