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)