Skip to content

Commit

Permalink
Fix load_all of null documents. (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
GunnarFarneback authored Jun 25, 2024
1 parent 4fd38bb commit 37e287e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 7 deletions.
20 changes: 15 additions & 5 deletions src/YAML.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/composer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/constructor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 37e287e

Please sign in to comment.