Skip to content

Commit

Permalink
add parse and parsefile functions (#302)
Browse files Browse the repository at this point in the history
closes #272
  • Loading branch information
JeffBezanson authored Dec 17, 2024
1 parent ce90511 commit 737f6f4
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
10 changes: 9 additions & 1 deletion src/read.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ Read JSON.
"""
function read(json::AbstractString; jsonlines::Bool=false,
numbertype::Union{DataType, Nothing}=nothing, kw...)
return parse(read_json_str(json); jsonlines, numbertype, kw...)
end

str = read_json_str(json)
function parse(str::AbstractString; jsonlines::Bool=false,
numbertype::Union{DataType, Nothing}=nothing, kw...)
buf = codeunits(str)
len = length(buf)
if len == 0
Expand Down Expand Up @@ -73,6 +76,11 @@ function read(json::AbstractString; jsonlines::Bool=false,
invalid(error, buf, pos, Any)
end

function parsefile(fname::AbstractString; jsonlines::Bool=false,
numbertype::Union{DataType, Nothing}=nothing, kw...)
return parse(VectorString(Mmap.mmap(fname)); jsonlines, numbertype, kw...)
end

macro check()
esc(quote
if (tapeidx + 1) > length(tape)
Expand Down
15 changes: 11 additions & 4 deletions src/structs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ function rawbytes end
read(io::Union{IO, Base.AbstractCmd}, ::Type{T}; kw...) where {T} = read(Base.read(io, String), T; kw...)
read(bytes::AbstractVector{UInt8}, ::Type{T}; kw...) where {T} = read(VectorString(bytes), T; kw...)

function _prepare_read(json::AbstractString, ::Type{T}) where {T}
str = read_json_str(json)
function _prepare_read(str::AbstractString, ::Type{T}) where {T}
buf = codeunits(str)
len = length(buf)
if len == 0
Expand All @@ -30,7 +29,7 @@ function _prepare_read(json::AbstractString, ::Type{T}) where {T}
invalid(error, buf, pos, T)
end

function read(str::AbstractString, ::Type{T}; jsonlines::Bool=false, kw...) where {T}
function parse(str::AbstractString, ::Type{T}; jsonlines::Bool=false, kw...) where {T}
buf, pos, len, b = _prepare_read(str, T)
if jsonlines
if StructType(T) != ArrayType()
Expand All @@ -43,13 +42,21 @@ function read(str::AbstractString, ::Type{T}; jsonlines::Bool=false, kw...) wher
return x
end

function read(str::AbstractString, ::Type{T}; jsonlines::Bool=false, kw...) where {T}
return parse(read_json_str(str), T; jsonlines, kw...)
end

function parsefile(fname::AbstractString, ::Type{T}; jsonlines::Bool=false, kw...) where {T}
return parse(VectorString(Mmap.mmap(fname)), T; jsonlines, kw...)
end

"""
JSON3.read!(json_str, x; kw...)
Incrementally update an instance of a mutable object `x` with the contents of `json_str`. See [`JSON3.read`](@ref) for more details.
"""
function read!(str::AbstractString, x::T; kw...) where {T}
buf, pos, len, b = _prepare_read(str, T)
buf, pos, len, b = _prepare_read(read_json_str(str), T)
pos, x = read!(StructType(T), buf, pos, len, b, T, x; kw...)
return x
end
Expand Down
26 changes: 14 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -167,18 +167,20 @@ StructTypes.StructType(::Type{UndefGuy}) = StructTypes.Mutable()

@testset "read.jl" begin

@test_throws ArgumentError JSON3.read("")
@test JSON3.read("{\"hey\":1}").hey == 1
@test JSON3.read("[\"hey\",1]") == ["hey",1]
@test JSON3.read("1.0") === Int64(1)
@test JSON3.read("1") === Int64(1)
@test JSON3.read("1.1") === 1.1
@test JSON3.read("+1.1") === 1.1
@test JSON3.read("-1.1") === -1.1
@test JSON3.read("\"hey\"") == "hey"
@test JSON3.read("null") === nothing
@test JSON3.read("true") === true
@test JSON3.read("false") === false
for readfunc in [JSON3.read, JSON3.parse]
@test_throws ArgumentError readfunc("")
@test readfunc("{\"hey\":1}").hey == 1
@test readfunc("[\"hey\",1]") == ["hey",1]
@test readfunc("1.0") === Int64(1)
@test readfunc("1") === Int64(1)
@test readfunc("1.1") === 1.1
@test readfunc("+1.1") === 1.1
@test readfunc("-1.1") === -1.1
@test readfunc("\"hey\"") == "hey"
@test readfunc("null") === nothing
@test readfunc("true") === true
@test readfunc("false") === false
end

# numbertype
@test JSON3.read("1.0", numbertype=Float64) === 1.0
Expand Down

0 comments on commit 737f6f4

Please sign in to comment.