Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Crystal JSON vs YAML serialization
require "json"
require "yaml"
require "secure_random"
class SerializableKlass
YAML.mapping({
bool: { type: Bool, nilable: true},
float: { type: Float64, nilable: true},
int: { type: Int32, nilable: true},
str: { type: String, nilable: true}
})
JSON.mapping({
bool: { type: Bool, nilable: true},
float: { type: Float64, nilable: true},
int: { type: Int32, nilable: true},
str: { type: String, nilable: true}
})
RANDOM = Random.new
macro add_to_yml(property)
unless {{property}}.nil?
yaml.nl
yaml << "{{property}}: #{@{{property}}}"
end
end
def initialize(bool : (Bool | Nil) = [RANDOM.next_bool, nil].sample,
str : (String | Nil) = [SecureRandom.hex, nil].sample,
float : (Float64 | Nil) = [RANDOM.next_float, nil].sample,
int : (Int32 | Nil) = [RANDOM.next_int, nil].sample)
@bool = bool
@str = str
@float = float
@int = int
end
def to_yaml(yaml : YAML::Generator)
yaml.indented do
add_to_yml(bool)
add_to_yml(str)
add_to_yml(float)
add_to_yml(int)
end
end
def ==(other)
return false unless other.is_a?(SerializableKlass)
other.bool == bool && \
other.str == str && \
other.float == float && \
other.int == int
end
end
require "spec"
describe SerializableKlass do
it "can be serialized to/from JSON" do
42.times do
object = SerializableKlass.new
SerializableKlass.from_json(object.to_json).should eq(object)
end
end
it "can be serialized to/from YAML" do
42.times do
object = SerializableKlass.new
SerializableKlass.from_yaml(object.to_yaml).should eq(object)
end
end
end
@Val

This comment has been minimized.

Copy link
Owner Author

commented Sep 12, 2016

JSON spec show a float serialization problem and YAML parse fail :-/

> crystal run crystal_json_vs_yaml_serialization.cr
FE

Failures:

  1) SerializableKlass can be serialized to/from JSON
     Failure/Error: SerializableKlass.from_json(object.to_json).should eq(object)

       expected: #<SerializableKlass:0x1ec2280 @bool=nil, @float=0.49257630703332284, @int=nil, @str="df694f7df279d1a4c0231f9ece0e6379">
            got: #<SerializableKlass:0x1ec21e0 @bool=nil, @float=0.49257630703332289, @int=nil, @str="df694f7df279d1a4c0231f9ece0e6379">

     # ./crystal_json_vs_yaml_serialization.cr:63

  2) SerializableKlass can be serialized to/from YAML

       expected MAPPING_START but was SCALAR at 1:0
       [4596631] *CallStack::unwind:Array(Pointer(Void)) +87
       [4596522] *CallStack#initialize:Array(Pointer(Void)) +10
       [4596474] *CallStack::new:CallStack +42
       [4572456] *raise<YAML::ParseException>:NoReturn +24
       [5017962] ???
       [5018424] *YAML::PullParser#expect_kind<LibYAML::EventType>:Nil +136
       [5018266] *YAML::PullParser#read<LibYAML::EventType>:LibYAML::EventType +10
       [5018459] *YAML::PullParser#read_mapping_start:LibYAML::EventType +11
       [4972229] *SerializableKlass#initialize<YAML::PullParser>:(String | Nil) +197
       [4972001] *SerializableKlass::new<YAML::PullParser>:SerializableKlass +129
       [4971803] *SerializableKlass +75
       [4572351] ~procProc(Nil) +79
       [4570245] *it<String, String, Int32, &Proc(Nil)>:(Array(Spec::Result) | Nil) +469
       [4569758] ~procProc(Nil) +126
       [4819383] *Spec::RootContext::describe<String, String, Int32, &Proc(Nil)>:Spec::Context+ +391
       [4569575] *describe<SerializableKlass:Class, String, Int32, &Proc(Nil)>:Spec::Context+ +55
       [4505376] ???
       [4562585] main +41
       [140125722131269] __libc_start_main +245
       [4501561] ???
       [0] ???

Finished in 380 microseconds
2 examples, 1 failures, 1 errors, 0 pending

Failed examples:

crystal spec ./crystal_json_vs_yaml_serialization.cr:60 # SerializableKlass can be serialized to/from JSON
crystal spec ./crystal_json_vs_yaml_serialization.cr:67 # SerializableKlass can be serialized to/from YAML
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.