Skip to content

Commit

Permalink
Merge pull request #29 from quinnj/jq/tuples
Browse files Browse the repository at this point in the history
Add support for hetergenously typed tuple readings and fix a struct t…
  • Loading branch information
quinnj authored Oct 16, 2019
2 parents 0ef582a + 50b2534 commit dbe01b5
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 43 deletions.
19 changes: 17 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
before_install:
- cd ../..
- mv $TRAVIS_REPO_SLUG _old
- git config --global core.autocrlf false
- git clone --depth=50 _old $TRAVIS_REPO_SLUG
- cd $TRAVIS_REPO_SLUG

language: julia

sudo: false

os:
- linux
- osx
- windows

arch:
- x64
- x86

julia:
- 1.0
- 1.1
- 1.3
- nightly

env:
- JULIA_PROJECT="@."

matrix:
exclude:
- os: osx
arch: x86
allow_failures:
- julia: nightly

notifications:
email: false

after_success:
- julia -e 'ENV["TRAVIS_JULIA_VERSION"] != "1.1" && ENV["TRAVIS_OS_NAME"] != "linux" && exit(); using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'ENV["TRAVIS_JULIA_VERSION"] == "1.3" && ENV["TRAVIS_OS_NAME"] != "linux" && exit(); using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
36 changes: 0 additions & 36 deletions appveyor.yml

This file was deleted.

2 changes: 1 addition & 1 deletion src/JSON3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,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 ExpectedComma ExpectedSemiColon InvalidChar
@enum Error UnexpectedEOF ExpectedOpeningObjectChar ExpectedOpeningQuoteChar ExpectedOpeningArrayChar ExpectedClosingArrayChar ExpectedComma ExpectedSemiColon InvalidChar

# AbstractDict interface
function Base.length(obj::Object)
Expand Down
74 changes: 70 additions & 4 deletions src/structs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,10 @@ StructType(::Type{<:Tuple}) = ArrayType()
construct(T, x::Vector{S}) where {S} = T(x)

@inline read(::ArrayType, buf, pos, len, b, ::Type{T}) where {T} = read(ArrayType(), buf, pos, len, b, T, Base.IteratorEltype(T) == Base.HasEltype() ? eltype(T) : Any)
@inline read(::ArrayType, buf, pos, len, b, ::Type{T}, ::Type{eT}) where {T, eT} = readarray(buf, pos, len, b, T, eT)
read(::ArrayType, buf, pos, len, b, ::Type{Tuple}, ::Type{eT}) where {eT} = readarray(buf, pos, len, b, Tuple, eT)

@inline function read(::ArrayType, buf, pos, len, b, ::Type{T}, ::Type{eT}) where {T, eT}
@inline function readarray(buf, pos, len, b, ::Type{T}, ::Type{eT}) where {T, eT}
if b != UInt8('[')
error = ExpectedOpeningArrayChar
@goto invalid
Expand All @@ -480,7 +482,7 @@ construct(T, x::Vector{S}) where {S} = T(x)
@wh
vals = Vector{eT}(undef, 0)
if b == UInt8(']')
return pos + 1, T(vals)
return pos + 1, construct(T, vals)
end
while true
# positioned at start of value
Expand All @@ -505,6 +507,70 @@ construct(T, x::Vector{S}) where {S} = T(x)
invalid(error, buf, pos, T)
end

@inline function read(::ArrayType, buf, pos, len, b, ::Type{T}, ::Type{eT}) where {T <: Tuple, eT}
if b != UInt8('[')
error = ExpectedOpeningArrayChar
@goto invalid
end
pos += 1
@eof
b = getbyte(buf, pos)
@wh
if b == UInt8(']')
pos += 1
return pos, T()
end
N = fieldcount(T)
Base.@nexprs 32 i -> begin
# positioned at start of value
eT_i = fieldtype(T, i)
pos, x_i = read(StructType(eT_i), buf, pos, len, b, eT_i)
@eof
b = getbyte(buf, pos)
@wh
if N == i
if b == UInt8(']')
return pos, Base.@ncall i tuple x
else
error = ExpectedClosingArrayChar
@goto invalid
end
elseif b != UInt8(',')
error = ExpectedComma
@goto invalid
end
pos += 1
@eof
b = getbyte(buf, pos)
@wh
end
vals = []
for i = 33:N
eT_i = fieldtype(T, i)
pos, y = read(StructType(eT_i), buf, pos, len, b, eT_i)
push!(vals, y)
@eof
b = getbyte(buf, pos)
@wh
if b == UInt8(']')
pos += 1
break
elseif b != UInt8(',')
error = ExpectedComma
@goto invalid
end
pos += 1
@eof
b = getbyte(buf, pos)
@wh
end
return pos, (x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_10, x_11, x_12, x_13, x_14, x_15, x_16,
x_17, x_18, x_19, x_20, x_21, x_22, x_23, x_24, x_25, x_26, x_27, x_28, x_29, x_30, x_31, x_32, vals...)

@label invalid
invalid(error, buf, pos, T)
end

StructType(::Type{<:AbstractDict}) = ObjectType()
StructType(::Type{<:NamedTuple}) = ObjectType()
StructType(::Type{<:Pair}) = ObjectType()
Expand Down Expand Up @@ -741,8 +807,8 @@ end
pos, y = readvalue(buf, pos, len, fieldtype(T, i))
push!(vals, y)
end
return pos, T(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16,
x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, vals...)
return pos, T(x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_10, x_11, x_12, x_13, x_14, x_15, x_16,
x_17, x_18, x_19, x_20, x_21, x_22, x_23, x_24, x_25, x_26, x_27, x_28, x_29, x_30, x_31, x_32, vals...)

@label invalid
invalid(error, buf, pos, T)
Expand Down
49 changes: 49 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,44 @@ struct AndFunction <: BinaryFunction
rhs::Expression
end

struct LotsOfFields
x1::String
x2::String
x3::String
x4::String
x5::String
x6::String
x7::String
x8::String
x9::String
x10::String
x11::String
x12::String
x13::String
x14::String
x15::String
x16::String
x17::String
x18::String
x19::String
x20::String
x21::String
x22::String
x23::String
x24::String
x25::String
x26::String
x27::String
x28::String
x29::String
x30::String
x31::String
x32::String
x33::String
x34::String
x35::String
end

@testset "JSON3" begin

@testset "read.jl" begin
Expand Down Expand Up @@ -489,6 +527,12 @@ expr = JSON3.read("""
@test JSON3.write(B) == "\"B\""
@test JSON3.write(Vehicle) == "\"Vehicle\""

JSON3.StructType(::Type{LotsOfFields}) = JSON3.Struct()
lotsoffields = LotsOfFields(fill("hey", 35)...)
jlots = JSON3.write(lotsoffields)
@test jlots == "{\"x1\":\"hey\",\"x2\":\"hey\",\"x3\":\"hey\",\"x4\":\"hey\",\"x5\":\"hey\",\"x6\":\"hey\",\"x7\":\"hey\",\"x8\":\"hey\",\"x9\":\"hey\",\"x10\":\"hey\",\"x11\":\"hey\",\"x12\":\"hey\",\"x13\":\"hey\",\"x14\":\"hey\",\"x15\":\"hey\",\"x16\":\"hey\",\"x17\":\"hey\",\"x18\":\"hey\",\"x19\":\"hey\",\"x20\":\"hey\",\"x21\":\"hey\",\"x22\":\"hey\",\"x23\":\"hey\",\"x24\":\"hey\",\"x25\":\"hey\",\"x26\":\"hey\",\"x27\":\"hey\",\"x28\":\"hey\",\"x29\":\"hey\",\"x30\":\"hey\",\"x31\":\"hey\",\"x32\":\"hey\",\"x33\":\"hey\",\"x34\":\"hey\",\"x35\":\"hey\"}"
@test JSON3.read(jlots, LotsOfFields) == lotsoffields

end # @testset "structs.jl"

@testset "show.jl" begin
Expand Down Expand Up @@ -587,4 +631,9 @@ obj = JSON3.read("{\"hey\":1}")
obj = JSON3.read("{\"a\":\"b\", \"b\":null, \"c\":[null,null]}")
@test copy(obj) == Dict(:a => "b", :b => nothing, :c => [nothing, nothing])

# better Tuple reading support
@test JSON3.read("[\"car\",\"Mercedes\"]", Tuple{Symbol, String}) == (:car, "Mercedes")
@test JSON3.read("[\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\",\"hey\"]", NTuple{35, String}) ==
("hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey", "hey")

end # @testset "JSON3"

0 comments on commit dbe01b5

Please sign in to comment.