Skip to content

Commit

Permalink
Showing 4 changed files with 87 additions and 1 deletion.
6 changes: 6 additions & 0 deletions spec/std/yaml/serialization_spec.cr
Original file line number Diff line number Diff line change
@@ -104,6 +104,12 @@ describe "YAML serialization" do
end
end
end

{% if Crystal::VERSION == "0.18.0" %}
it "deserializes union" do
Array(Int32 | String).from_yaml(%([1, "hello"])).should eq([1, "hello"])
end
{% end %}
end

describe "to_yaml" do
17 changes: 17 additions & 0 deletions spec/std/yaml/yaml_pull_parser_spec.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
require "spec"
require "yaml"

private def assert_raw(string, expected = string, file = __FILE__, line = __LINE__)
it "parses raw #{string.inspect}", file, line do
pull = YAML::PullParser.new(string)
pull.read_stream do
pull.read_document do
pull.read_raw.should eq(expected)
end
end
end
end

module YAML
describe PullParser do
it "reads empty stream" do
@@ -95,5 +106,11 @@ module YAML
end
end
end

assert_raw %(hello)
assert_raw %("hello"), %(hello)
assert_raw %(["hello"])
assert_raw %(["hello","world"])
assert_raw %({"hello":"world"})
end
end
20 changes: 19 additions & 1 deletion src/yaml/from_yaml.cr
Original file line number Diff line number Diff line change
@@ -29,7 +29,11 @@ end

{% for type in %w(Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64) %}
def {{type.id}}.new(pull : YAML::PullParser)
{{type.id}}.new(pull.read_scalar)
begin
{{type.id}}.new(pull.read_scalar)
rescue ex
raise YAML::ParseException.new(ex.message.not_nil!, 0, 0)
end
end
{% end %}

@@ -133,6 +137,20 @@ def Enum.new(pull : YAML::PullParser)
end
end

{% if Crystal::VERSION == "0.18.0" %}
def Union.new(pull : YAML::PullParser)
string = pull.read_raw
\{% for type in T %}
begin
return \{{type}}.from_yaml(string)
rescue YAML::ParseException
# Ignore
end
\{% end %}
raise YAML::ParseException.new("couldn't parse #{self} from #{string}", 0, 0)
end
{% end %}

struct Time::Format
def from_yaml(pull : YAML::PullParser)
string = pull.read_scalar
45 changes: 45 additions & 0 deletions src/yaml/pull_parser.cr
Original file line number Diff line number Diff line change
@@ -147,6 +147,51 @@ class YAML::PullParser
read_next
end

def read_raw
case kind
when EventKind::SCALAR
self.value.not_nil!.tap { read_next }
when EventKind::SEQUENCE_START, EventKind::MAPPING_START
String.build { |io| read_raw(io) }
else
parse_exception "unexpected kind: #{kind}"
end
end

def read_raw(io)
case kind
when EventKind::SCALAR
self.value.not_nil!.inspect(io)
read_next
when EventKind::SEQUENCE_START
io << "["
read_next
first = true
while kind != EventKind::SEQUENCE_END
io << "," unless first
read_raw(io)
first = false
end
io << "]"
read_next
when EventKind::MAPPING_START
io << "{"
read_next
first = true
while kind != EventKind::MAPPING_END
io << "," unless first
read_raw(io)
io << ":"
read_raw(io)
first = false
end
io << "}"
read_next
else
parse_exception "unexpected kind: #{kind}"
end
end

def skip
case kind
when EventKind::SCALAR

0 comments on commit 8bfa519

Please sign in to comment.