diff --git a/src/YAML.jl b/src/YAML.jl index 8b12368..d5a7067 100644 --- a/src/YAML.jl +++ b/src/YAML.jl @@ -27,6 +27,11 @@ using Dates using Printf using StringEncodings +# Singleton object used to indicate that a stream contains no document +# content, i.e. whitespace and comments only. +struct MissingDocument end +const missing_document = MissingDocument() + include("versions.jl") include("queue.jl") include("buffered_input.jl") @@ -74,13 +79,18 @@ function load(tokenstream::TokenStream, constructor::Constructor) end load(input::IO, constructor::Constructor) = - load(TokenStream(input), constructor) + missing_to_nothing(load(TokenStream(input), constructor)) load(ts::TokenStream, more_constructors::_constructor = nothing, multi_constructors::Dict = Dict(); dicttype::_dicttype = Dict{Any, Any}, constructorType::Function = SafeConstructor) = load(ts, constructorType(_patch_constructors(more_constructors, dicttype), multi_constructors)) load(input::IO, more_constructors::_constructor = nothing, multi_constructors::Dict = Dict(); kwargs...) = - load(TokenStream(input), more_constructors, multi_constructors ; kwargs...) + missing_to_nothing(load(TokenStream(input), more_constructors, multi_constructors ; kwargs...)) + +# When doing `load` or `load_file` of something that doesn't start any +# document, return `nothing`. +missing_to_nothing(::MissingDocument) = nothing +missing_to_nothing(x) = x """ YAMLDocIterator @@ -96,7 +106,7 @@ mutable struct YAMLDocIterator function YAMLDocIterator(input::IO, constructor::Constructor) it = new(input, TokenStream(input), constructor, nothing) - it.next_doc = eof(it.input) ? nothing : load(it.ts, it.constructor) + it.next_doc = eof(it.input) ? missing_document : load(it.ts, it.constructor) return it end end @@ -110,10 +120,10 @@ Base.IteratorSize(::YAMLDocIterator) = Base.SizeUnknown() # Iteration protocol. function iterate(it::YAMLDocIterator, _ = nothing) - it.next_doc === nothing && return nothing + it.next_doc === missing_document && return nothing doc = it.next_doc if eof(it.input) - it.next_doc = nothing + it.next_doc = missing_document else reset!(it.ts) it.next_doc = load(it.ts, it.constructor) diff --git a/src/composer.jl b/src/composer.jl index bc8bf67..8d491af 100644 --- a/src/composer.jl +++ b/src/composer.jl @@ -41,7 +41,7 @@ end function compose_document(composer::Composer) - peek(composer.input) isa StreamEndEvent && return nothing + peek(composer.input) isa StreamEndEvent && return missing_document @assert forward!(composer.input) isa DocumentStartEvent node = compose_node(composer) @assert forward!(composer.input) isa DocumentEndEvent diff --git a/src/constructor.jl b/src/constructor.jl index 89b003b..88be658 100644 --- a/src/constructor.jl +++ b/src/constructor.jl @@ -56,7 +56,7 @@ function construct_document(constructor::Constructor, node::Node) data end -construct_document(::Constructor, ::Nothing) = nothing +construct_document(::Constructor, ::MissingDocument) = missing_document function construct_object(constructor::Constructor, node::Node) if haskey(constructor.constructed_objects, node) diff --git a/test/runtests.jl b/test/runtests.jl index fde4680..76a908f 100755 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -450,4 +450,19 @@ end # end end +# issue #226 - loadall stops on a null document +@testset "issue #226" begin + @test collect(YAML.load_all("null")) == [nothing] + input = """ + --- + 1 + --- + null + --- + 2 + """ + expected = [1, nothing, 2] + @test collect(YAML.load_all(input)) == expected +end + end # module