Skip to content

Commit 7ca4166

Browse files
committed
Fix #6 by supporting AbstractString inputs
1 parent 25f4741 commit 7ca4166

File tree

2 files changed

+76
-62
lines changed

2 files changed

+76
-62
lines changed

src/Parsers.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function parse end
239239
"Attempt to parse a value of type `T` from `IO` `io`. Returns `nothing` on parser failures and invalid values."
240240
function tryparse end
241241

242-
function parse(str::String, ::Type{T}; kwargs...) where {T}
242+
function parse(str::AbstractString, ::Type{T}; kwargs...) where {T}
243243
io = IOBuffer(str)
244244
res = parse(defaultparser, io, T; kwargs...)
245245
return ok(res.code) ? res.result : throw(Error(io, res))
@@ -248,7 +248,7 @@ function parse(io::IO, ::Type{T}; kwargs...) where {T}
248248
res = parse(defaultparser, io, T; kwargs...)
249249
return ok(res.code) ? res.result : throw(Error(io, res))
250250
end
251-
function parse(f::Base.Callable, str::String, ::Type{T}; kwargs...) where {T}
251+
function parse(f::Base.Callable, str::AbstractString, ::Type{T}; kwargs...) where {T}
252252
io = IOBuffer(str)
253253
res = parse!(f, io, Result(T); kwargs...)
254254
return ok(res.code) ? res.result : throw(Error(io, res))
@@ -258,15 +258,15 @@ function parse(f::Base.Callable, io::IO, ::Type{T}; kwargs...) where {T}
258258
return ok(res.code) ? res.result : throw(Error(io, res))
259259
end
260260

261-
function tryparse(str::String, ::Type{T}; kwargs...) where {T}
261+
function tryparse(str::AbstractString, ::Type{T}; kwargs...) where {T}
262262
res = parse(defaultparser, IOBuffer(str), T; kwargs...)
263263
return ok(res.code) ? res.result : nothing
264264
end
265265
function tryparse(io::IO, ::Type{T}; kwargs...) where {T}
266266
res = parse(defaultparser, io, T; kwargs...)
267267
return ok(res.code) ? res.result : nothing
268268
end
269-
function tryparse(f::Base.Callable, str::String, ::Type{T}; kwargs...) where {T}
269+
function tryparse(f::Base.Callable, str::AbstractString, ::Type{T}; kwargs...) where {T}
270270
res = parse!(f, IOBuffer(str), Result(T); kwargs...)
271271
return ok(res.code) ? res.result : nothing
272272
end

test/runtests.jl

Lines changed: 72 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -501,64 +501,6 @@ include("floats.jl")
501501
include("dates.jl")
502502
include("bools.jl")
503503

504-
@testset "Misc" begin
505-
506-
@test Parsers.parse("101", Int) === 101
507-
@test Parsers.parse("101,101", Float64; decimal=',') === 101.101
508-
@test Parsers.parse(IOBuffer("true"), Bool) === true
509-
@test_throws Parsers.Error Parsers.parse("abc", Int)
510-
511-
@test Parsers.tryparse("abc", Int) === nothing
512-
@test Parsers.tryparse(IOBuffer("101,101"), Float32; decimal=',') === Float32(101.101)
513-
514-
# custom parser
515-
function int2str(io::IO, r::Parsers.Result{Int}, args...)
516-
v = 0
517-
while !eof(io) && (UInt8('0') <= Parsers.peekbyte(io) <= UInt8('9'))
518-
v *= 10
519-
v += Int(Parsers.readbyte(io) - UInt8('0'))
520-
end
521-
r.result = v
522-
r.code = OK
523-
return r
524-
end
525-
526-
@test Parsers.parse(int2str, "101", Int) === 101
527-
@test Parsers.parse(int2str, IOBuffer("101"), Int) === 101
528-
@test Parsers.tryparse(int2str, "101", Int) === 101
529-
@test Parsers.tryparse(int2str, IOBuffer("101"), Int) === 101
530-
531-
@test Parsers.parse("01/20/2018", Date; dateformat="mm/dd/yyyy") === Date(2018, 1, 20)
532-
533-
@test_throws Parsers.Error Parsers.parse("", Missing)
534-
@test Parsers.tryparse("", Missing) === nothing
535-
536-
r = Parsers.parse(Parsers.Quoted('{', '}', '\\'), IOBuffer("{1}"), Int)
537-
@test r.result === 1
538-
@test r.code === OK | QUOTED | EOF
539-
@test r.pos == 0
540-
541-
let io=IOBuffer("1,2,null,4"), layers=Parsers.Delimited(Parsers.Quoted(Parsers.Sentinel(["null"])))
542-
r = Parsers.parse(layers, io, Int)
543-
@test r.result === 1
544-
@test r.code === OK | DELIMITED
545-
@test r.pos == 0
546-
r = Parsers.parse(layers, io, Int)
547-
@test r.result === 2
548-
@test r.code === OK | DELIMITED
549-
@test r.pos == 2
550-
r = Parsers.parse(layers, io, Int)
551-
@test r.result === missing
552-
@test r.code === SENTINEL | DELIMITED
553-
@test r.pos == 4
554-
r = Parsers.parse(layers, io, Int)
555-
@test r.result === 4
556-
@test r.code === OK | EOF
557-
@test r.pos == 9
558-
end
559-
560-
end # @testset
561-
562504
@testset "ignore repeated delimiters" begin
563505

564506
let io=IOBuffer("1,,,2,null,4"), layers=Parsers.Delimited(Parsers.Quoted(Parsers.Sentinel(["null"])); ignore_repeated=true)
@@ -651,4 +593,76 @@ end
651593

652594
end # @testset
653595

596+
@testset "Misc" begin
597+
598+
@test Parsers.parse("101", Int) === 101
599+
@test Parsers.parse("101,101", Float64; decimal=',') === 101.101
600+
@test Parsers.parse(IOBuffer("true"), Bool) === true
601+
@test_throws Parsers.Error Parsers.parse("abc", Int)
602+
603+
@test Parsers.tryparse("abc", Int) === nothing
604+
@test Parsers.tryparse(IOBuffer("101,101"), Float32; decimal=',') === Float32(101.101)
605+
606+
# custom parser
607+
function int2str(io::IO, r::Parsers.Result{Int}, args...)
608+
v = 0
609+
while !eof(io) && (UInt8('0') <= Parsers.peekbyte(io) <= UInt8('9'))
610+
v *= 10
611+
v += Int(Parsers.readbyte(io) - UInt8('0'))
612+
end
613+
r.result = v
614+
r.code = OK
615+
return r
616+
end
617+
618+
@test Parsers.parse(int2str, "101", Int) === 101
619+
@test Parsers.parse(int2str, IOBuffer("101"), Int) === 101
620+
@test Parsers.tryparse(int2str, "101", Int) === 101
621+
@test Parsers.tryparse(int2str, IOBuffer("101"), Int) === 101
622+
623+
@test Parsers.parse("01/20/2018", Date; dateformat="mm/dd/yyyy") === Date(2018, 1, 20)
624+
625+
@test_throws Parsers.Error Parsers.parse("", Missing)
626+
@test Parsers.tryparse("", Missing) === nothing
627+
628+
r = Parsers.parse(Parsers.Quoted('{', '}', '\\'), IOBuffer("{1}"), Int)
629+
@test r.result === 1
630+
@test r.code === OK | QUOTED | EOF
631+
@test r.pos == 0
632+
633+
let io=IOBuffer("1,2,null,4"), layers=Parsers.Delimited(Parsers.Quoted(Parsers.Sentinel(["null"])))
634+
r = Parsers.parse(layers, io, Int)
635+
@test r.result === 1
636+
@test r.code === OK | DELIMITED
637+
@test r.pos == 0
638+
r = Parsers.parse(layers, io, Int)
639+
@test r.result === 2
640+
@test r.code === OK | DELIMITED
641+
@test r.pos == 2
642+
r = Parsers.parse(layers, io, Int)
643+
@test r.result === missing
644+
@test r.code === SENTINEL | DELIMITED
645+
@test r.pos == 4
646+
r = Parsers.parse(layers, io, Int)
647+
@test r.result === 4
648+
@test r.code === OK | EOF
649+
@test r.pos == 9
650+
end
651+
652+
# 6: AbstractString input
653+
@test Parsers.parse(SubString("101"), Int) === 101
654+
@test Parsers.parse(SubString("101,101"), Float64; decimal=',') === 101.101
655+
@test Parsers.parse(IOBuffer("true"), Bool) === true
656+
@test_throws Parsers.Error Parsers.parse("abc", Int)
657+
658+
@test Parsers.tryparse("abc", Int) === nothing
659+
@test Parsers.tryparse(IOBuffer(SubString("101,101")), Float32; decimal=',') === Float32(101.101)
660+
661+
@test Parsers.parse(int2str, SubString("101"), Int) === 101
662+
@test Parsers.parse(int2str, IOBuffer(SubString("101")), Int) === 101
663+
@test Parsers.tryparse(int2str, SubString("101"), Int) === 101
664+
@test Parsers.tryparse(int2str, IOBuffer(SubString("101")), Int) === 101
665+
666+
end # @testset
667+
654668
end # @testset

0 commit comments

Comments
 (0)