diff --git a/spec/cbor/serializable_spec.cr b/spec/cbor/serializable_spec.cr index 1019af0..1dbe4cf 100644 --- a/spec/cbor/serializable_spec.cr +++ b/spec/cbor/serializable_spec.cr @@ -36,6 +36,34 @@ class ExampleUnmapped property a : Int32 end +class Location + include CBOR::Serializable + + @[CBOR::Field(key: "lat")] + property latitude : Float64 + + @[CBOR::Field(key: "lng")] + property longitude : Float64 + + def initialize(@latitude, @longitude) + end +end + +class House + include CBOR::Serializable + property address : String + property location : Location? + + def initialize(@address, @location) + end +end + +struct A + include CBOR::Serializable + @a : Int32 + @b : Float64 = 1.0 +end + describe CBOR::Serializable do describe "rfc examples" do describe %(example {_ "a": 1, "b": [_ 2, 3]}) do @@ -84,4 +112,35 @@ describe CBOR::Serializable do result.cbor_unmapped.should eq({"b" => [2, 3]}) end end + + describe "documentation examples" do + describe "house example" do + houses = [House.new(address: "Crystal Road 1234", location: Location.new(latitude: 12.3, longitude: 34.5))] + cbor_houses_bytes = Bytes[129, 191, 103, 97, 100, 100, 114, 101, 115, 115, 113, 67, 114, 121, 115, 116, 97, 108, 32, 82, 111, 97, 100, 32, 49, 50, 51, 52, 104, 108, 111, 99, 97, 116, 105, 111, 110, 191, 99, 108, 97, 116, 251, 64, 40, 153, 153, 153, 153, 153, 154, 99, 108, 110, 103, 251, 64, 65, 64, 0, 0, 0, 0, 0, 255, 255] + + it "encodes to cbor" do + cbor = houses.to_cbor + cbor.should eq(cbor_houses_bytes) + end + + it "decodes form cbor" do + decoded = Array(House).from_cbor(cbor_houses_bytes) + + decoded.size.should eq(1) + house = decoded[0] + house.address.should eq("Crystal Road 1234") + + loc = house.location + loc.should_not be_nil + loc.not_nil!.latitude.should eq(12.3) + loc.not_nil!.longitude.should eq(34.5) + end + end + + describe "default values example" do + it "respects default values" do + A.from_cbor({"a" => 1}.to_cbor).inspect.should eq("A(@a=1, @b=1.0)") + end + end + end end diff --git a/src/cbor/decoder.cr b/src/cbor/decoder.cr index 62240ad..66ba0f7 100644 --- a/src/cbor/decoder.cr +++ b/src/cbor/decoder.cr @@ -101,7 +101,8 @@ class CBOR::Decoder end def read_nil_or - if @current_token.is_a?(Token::SimpleValueT) && @current_token.value.is_nil? + token = @current_token + if token.is_a?(Token::SimpleValueT) && token.value.is_nil? finish_token! nil else diff --git a/src/cbor/encoder.cr b/src/cbor/encoder.cr index 4d654ab..945ed7e 100644 --- a/src/cbor/encoder.cr +++ b/src/cbor/encoder.cr @@ -170,8 +170,9 @@ class CBOR::Encoder end def to_slice : Bytes - raise Error.new("to slice not implemented for io type: #{typeof(io)}") unless io.responds_to?(:to_slice) - @io.to_slice + io = @io + raise "to slice not implemented for io type: #{typeof(io)}" unless io.responds_to?(:to_slice) + io.to_slice end def to_s : String diff --git a/src/cbor/serializable.cr b/src/cbor/serializable.cr index 8057471..51e577a 100644 --- a/src/cbor/serializable.cr +++ b/src/cbor/serializable.cr @@ -25,15 +25,14 @@ module CBOR # property location : Location? # end # - # XXXX -----> TODO: CHANGE HERE!! - # house = House.from_json(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}})) + # house = House.from_cbor(Bytes[191, 103, 97, 100, 100, 114, 101, 115, 115, 113, 67, 114, 121, 115, 116, 97, 108, 32, 82, 111, 97, 100, 32, 49, 50, 51, 52, 104, 108, 111, 99, 97, 116, 105, 111, 110, 191, 99, 108, 97, 116, 251, 64, 40, 153, 153, 153, 153, 153, 154, 99, 108, 110, 103, 251, 64, 65, 64, 0, 0, 0, 0, 0, 255, 255]) # house.address # => "Crystal Road 1234" # house.location # => # - # house.to_json # => %({"address":"Crystal Road 1234","location":{"lat":12.3,"lng":34.5}}) + # house.to_cbor # => Bytes[191, 103, 97, 100, 100, 114, 101, 115, 115, 113, 67, 114, 121, 115, 116, 97, 108, 32, 82, 111, 97, 100, 32, 49, 50, 51, 52, 104, 108, 111, 99, 97, 116, 105, 111, 110, 191, 99, 108, 97, 116, 251, 64, 40, 153, 153, 153, 153, 153, 154, 99, 108, 110, 103, 251, 64, 65, 64, 0, 0, 0, 0, 0, 255, 255] # - # houses = Array(House).from_json(%([{"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}])) + # houses = Array(House).from_json(Bytes[129, 191, 103, 97, 100, 100, 114, 101, 115, 115, 113, 67, 114, 121, 115, 116, 97, 108, 32, 82, 111, 97, 100, 32, 49, 50, 51, 52, 104, 108, 111, 99, 97, 116, 105, 111, 110, 191, 99, 108, 97, 116, 251, 64, 40, 153, 153, 153, 153, 153, 154, 99, 108, 110, 103, 251, 64, 65, 64, 0, 0, 0, 0, 0, 255, 255]) # houses.size # => 1 - # houses.to_json # => %([{"address":"Crystal Road 1234","location":{"lat":12.3,"lng":34.5}}]) + # houses.to_json # => Bytes[129, 191, 103, 97, 100, 100, 114, 101, 115, 115, 113, 67, 114, 121, 115, 116, 97, 108, 32, 82, 111, 97, 100, 32, 49, 50, 51, 52, 104, 108, 111, 99, 97, 116, 105, 111, 110, 191, 99, 108, 97, 116, 251, 64, 40, 153, 153, 153, 153, 153, 154, 99, 108, 110, 103, 251, 64, 65, 64, 0, 0, 0, 0, 0, 255, 255] # ``` # # ### Usage @@ -77,7 +76,7 @@ module CBOR # @b : Float64 = 1.0 # end # - # A.from_json(%<{"a":1}>) # => A(@a=1, @b=1.0) #TODO ----- FIX THIS!!!! + # A.from_cbor({"a" => 1}.to_cbor) # => A(@a=1, @b=1.0) # ``` # # ### Extensions: `CBOR::Serializable::Unmapped`. @@ -86,7 +85,7 @@ module CBOR # document will be stored in a `Hash(String, CBOR::Type)`. On serialization, any keys inside cbor_unmapped # will be serialized and appended to the current json object. # ``` - # require "json" + # require "cbor" # # struct A # include JSON::Serializable @@ -277,7 +276,7 @@ module CBOR {% end %} # Write the key of the map - write({{value[:key]}}) + cbor.write({{value[:key]}}) {% if value[:converter] %} if _{{name}} @@ -312,7 +311,7 @@ module CBOR protected def on_to_cbor(cbor : ::CBOR::Encoder) cbor_unmapped.each do |key, value| - write(key) + cbor.write(key) value.to_cbor(cbor) end end