~arestifo/crystal-cbor

crystal-cbor: Limit hash keys to certain types, and basic tests. v1 NEEDS REVISION

This patchset includes two very important things:

- limiting hash
keys to integers, floats, bytes and strings
- tests for the CBOR class
in general (basic types, arrays, hashes...).

And that is probably the
last commit I had left to submit!

It took me a whole day to get into
the code I left 7 months ago and make these PRs.
My commits weren't
even in order.
So I hope everything will be okay.

Have a nice day!

Karchnu (2):
  Limit hash keys to certain types.
  Add CBOR tests on basic cases and types.

 spec/cbor_spec.cr   | 112 +++++++++++++++++++++++++++++++++++++++++++-
 src/cbor.cr         |  10 +++-
 src/cbor/decoder.cr |  35 +++++++++++++-
 3 files changed, 153 insertions(+), 4 deletions(-)

-- 
2.30.2
#530339 .build.yml failed
crystal-cbor/patches/.build.yml: FAILED in 18s

[Limit hash keys to certain types, and basic tests.][0] from [~karchnu][1]

[0]: https://lists.sr.ht/~arestifo/crystal-cbor/patches/23429
[1]: mailto:karchnu@karchnu.fr

✗ #530339 FAILED crystal-cbor/patches/.build.yml https://builds.sr.ht/~arestifo/job/530339
Path applied,
Thanks!

Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~arestifo/crystal-cbor/patches/23429/mbox | git am -3
Learn more about email & git

[PATCH crystal-cbor 1/2] Limit hash keys to certain types. Export this patch

From: Karchnu <karchnu@karchnu.fr>

---
 src/cbor.cr         | 10 +++++++++-
 src/cbor/decoder.cr | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/cbor.cr b/src/cbor.cr
index c3c33ef..eb18998 100644
--- a/src/cbor.cr
+++ b/src/cbor.cr
@@ -5,13 +5,21 @@ require "./cbor/**"
module CBOR
  VERSION = "0.1.0"

  # Represents CBOR Hash Keys: everything except Nil, hashs, arrays.
  alias HashKeyType = Int8  | Int16  | Int32  | Int64  | Int128 |
                      UInt8 | UInt16 | UInt32 | UInt64 |
                      Float32 | Float64 |
                      String |
                      Bool |
                      Bytes

  # Represents CBOR types
  alias Type = Nil |
               Bool |
               String |
               Bytes |
               Array(Type) |
               Hash(Type, Type) |
               Hash(HashKeyType,  Type) |
               Int8 |
               UInt8 |
               Int16 |
diff --git a/src/cbor/decoder.cr b/src/cbor/decoder.cr
index 510fb45..dae9c07 100644
--- a/src/cbor/decoder.cr
+++ b/src/cbor/decoder.cr
@@ -7,6 +7,34 @@ class CBOR::Decoder
    @current_token = @lexer.next_token
  end

  # This is similar to read_value but with a focus on a key for a hash.
  def read_key : HashKeyType
    v = case token = @current_token
    when Token::StringT
      finish_token!
      token.value.as(String)
    when Token::IntT
      finish_token!
      token.value
    when Token::FloatT
      finish_token!
      token.value
    when Token::BytesT
      finish_token!
      token.value.as(Bytes)
    when Token::SimpleValueT
      finish_token!
      token.value.to_t
    else
      puts "hash key with a #{token.class.to_s} value"
      unexpected_token(token)
    end
    if v.nil?
      raise ""
    end
    v
  end

  def read_value : Type
    case token = @current_token
    when Token::TagT
@@ -34,8 +62,11 @@ class CBOR::Decoder
      arr
    when Token::MapT
      finish_token!
      map = Hash(Type, Type).new
      consume_sequence(token.size) { map[read_value] = read_value }
      map = Hash(HashKeyType, Type).new
      consume_sequence(token.size) {
        key = read_key
        map[key] = read_value
      }
      map
    else
      unexpected_token(token)
-- 
2.30.2

[PATCH crystal-cbor 2/2] Add CBOR tests on basic cases and types. Export this patch

From: Karchnu <karchnu@karchnu.fr>

---
 spec/cbor_spec.cr | 112 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/spec/cbor_spec.cr b/spec/cbor_spec.cr
index 4d6dc79..ed1b0ac 100644
--- a/spec/cbor_spec.cr
+++ b/spec/cbor_spec.cr
@@ -1,5 +1,115 @@
require "./spec_helper"

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)
  end
end

class Person
  include CBOR::Serializable
  include CBOR::Serializable::Unmapped

  property name : String?
  def initialize(@name = nil)
  end
end


describe CBOR do
  # TODO: Write tests
  describe "basics: to_cbor" do
    it "empty array" do
      empty_array_cbor = [] of Nil
      empty_array_cbor.to_cbor.hexstring.should eq "80"
    end

    it "array - strings" do
      ["a", "b", "c"].to_cbor.hexstring.should eq "83616161626163"
    end

    it "empty hash" do
      empty = {} of Nil => Nil
      cbor_stuff = empty.to_cbor
      cbor_stuff.hexstring.should eq "a0"
    end

    it "hash" do
      {"a" => 10, "b" => true, "c" => nil}.to_cbor.hexstring.should eq "a361610a6162f56163f6"
    end

    it "union String | Int32" do
      value = (String | Int32).from_cbor(30.to_cbor).to_cbor
      value.hexstring.should eq "181e"
    end
    it "union (String | Int32)" do
      value = (String | Int32).from_cbor("blah".to_cbor).to_cbor
      value.hexstring.should eq "64626c6168"
    end
    it "union (Bool | Int32)" do
      value = (Bool | Int32).from_cbor(30.to_cbor).to_cbor
      value.hexstring.should eq "181e"
    end
    it "union (Bool | Int32)" do
      value = (Bool | Int32).from_cbor(false.to_cbor).to_cbor
      value.hexstring.should eq "f4"
    end
    it "union (String | Bool | Int32)" do
      value = (String | Bool | Int32).from_cbor("hello".to_cbor).to_cbor
      value.hexstring.should eq "6568656c6c6f"
    end
    it "union (String | Nil | Int32)" do
      value = (String | Nil | Int32).from_cbor(nil.to_cbor).to_cbor
      value.hexstring.should eq "f6"
    end
  end

  describe "CBOR library annotations and features" do
    it "House#to_cbor with CBOR::Field annotations" do
      house = House.new "my address"
      house.location = Location.new 1.1, 1.2
      house.to_cbor.hexstring.should eq "a267616464726573736a6d792061646472657373686c6f636174696f6ea2636c6174fb3ff199999999999a636c6e67fb3ff3333333333333"
    end

    it "House#from_cbor with CBOR::Field annotations" do
      other_house = House.new "my address"
      other_house.location = Location.new 1.1, 1.2

      house = House.from_cbor other_house.to_cbor
      house.to_cbor.hexstring.should eq "a267616464726573736a6d792061646472657373686c6f636174696f6ea2636c6174fb3ff199999999999a636c6e67fb3ff3333333333333"
    end

    it "Person#from_cbor with unmapped values" do
      h = Hash(String | Int32, String | Int32).new
      h["name"] = "Alice"
      h["age"]  = 30
      h["size"] = 160
      alice = Person.from_cbor h.to_cbor
      alice.to_cbor.hexstring.should eq "a3646e616d6565416c69636563616765181e6473697a6518a0"
    end

    it "Person#to_cbor with unmapped values" do
      alice = Person.new "Alice"
      alice.cbor_unmapped["age"] = 30
      alice.cbor_unmapped["size"] = 160
      alice.to_cbor.hexstring.should eq "a3646e616d6565416c69636563616765181e6473697a6518a0"
    end
  end
end

-- 
2.30.2
crystal-cbor/patches/.build.yml: FAILED in 18s

[Limit hash keys to certain types, and basic tests.][0] from [~karchnu][1]

[0]: https://lists.sr.ht/~arestifo/crystal-cbor/patches/23429
[1]: mailto:karchnu@karchnu.fr

✗ #530339 FAILED crystal-cbor/patches/.build.yml https://builds.sr.ht/~arestifo/job/530339
Path applied,
Thanks!