From 14c52208a38b017c29b5bbddebfe0f6834b9d570 Mon Sep 17 00:00:00 2001 From: Alberto Restifo Date: Sat, 25 Apr 2020 18:13:56 +0200 Subject: [PATCH] Add named tuple support --- spec/cbor/from_cbor_spec.cr | 1 + src/cbor/from_cbor.cr | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/spec/cbor/from_cbor_spec.cr b/spec/cbor/from_cbor_spec.cr index 56f6f3a..3f7a623 100644 --- a/spec/cbor/from_cbor_spec.cr +++ b/spec/cbor/from_cbor_spec.cr @@ -38,6 +38,7 @@ describe "CBOR helpers on basic types" do {Hash(UInt8, UInt8), Bytes[0xa2, 0x01, 0x02, 0x03, 0x04], Hash(UInt8, UInt8){1 => 2, 3 => 4}}, {TestEnum, Bytes[0x1a, 0x00, 0x00, 0x00, 0x01], TestEnum::Foo}, {Tuple(Int8, Int8), Bytes[0x82, 0x01, 0x02], {1_i8, 2_i8}}, + {NamedTuple(a: UInt8, b: Array(UInt8)), Bytes[0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03], {a: 1_u8, b: [2_u8, 3_u8]}}, ] tests.each do |tt| diff --git a/src/cbor/from_cbor.cr b/src/cbor/from_cbor.cr index 43a2a3d..f032520 100644 --- a/src/cbor/from_cbor.cr +++ b/src/cbor/from_cbor.cr @@ -99,6 +99,32 @@ def Tuple.new(decoder : CBOR::Decoder) {% end %} end +def NamedTuple.new(decoder : CBOR::Decoder) + {% begin %} + {% for key in T.keys %} + %var{key.id} = nil + {% end %} + + decoder.consume_hash do + key = decoder.read_string + case key + {% for key, type in T %} + when {{key.stringify}} + %var{key.id} = {{type}}.new(decoder) + {% end %} + else + raise CBOR::ParseError.new("Missing attribute: #{key}") + end + end + + { + {% for key, type in T %} + {{key}}: %var{key.id}.as({{type}}), + {% end %} + } + {% end %} +end + # Reads the CBOR values as a time. The value must be surrounded by a time tag as # specified by [Section 2.4.1 of RFC 7049][1]. #