diff --git a/src/kmer.gleam b/src/kmer.gleam index 7d0e682..bdc0b5d 100644 --- a/src/kmer.gleam +++ b/src/kmer.gleam @@ -2,6 +2,7 @@ import birl.{type Time} import gleam/bit_array import gleam/list.{reverse} import gleam/result.{try} +import gleam/uri.{type Uri} import ieee_float.{ type IEEEFloat, finite, from_bytes_16_be, from_bytes_32_be, from_bytes_64_be, multiply, power, round, @@ -16,6 +17,12 @@ pub type DecodedValue { Array(List(DecodedValue)) Map(List(#(DecodedValue, DecodedValue))) DateTime(Time) + EncodedCBOR(value: BitArray) + URI(Uri) + BigNum(bytes: BitArray, negative: Bool) + Base64(value: String) + Base64URL(value: String) + Mime(value: String) Null Undefined } @@ -29,6 +36,9 @@ pub type DecodeResult = pub opaque type DecodeError { // Malformed sequence found Malformed + + // Not implemented + NotImplemented } pub fn decode(bits: BitArray) -> DecodeResult { @@ -113,6 +123,17 @@ fn decode_tag(bits: BitArray) -> DecodeResult { case tag { 0 -> decode_datestring(rest) |> map_decoded(DateTime) 1 -> decode_unixtime(rest) |> map_decoded(DateTime) + 2 -> decode_bigint(rest, False) + 3 -> decode_bigint(rest, True) + // not willing to implement bigfloats tbh + 4 -> Error(NotImplemented) + // todo + 21 -> Error(NotImplemented) + // todo + 22 -> Error(NotImplemented) + // todo + 23 -> Error(NotImplemented) + 24 -> decode_bytestring(rest) |> map_decoded(EncodedCBOR) // CBOR magic number (no-op for us) 55_799 -> decode(rest) _ -> Error(Malformed) @@ -158,6 +179,17 @@ fn decode_unixtime(bits: BitArray) -> DecoderResult(Time) { } } +fn decode_bigint(bits: BitArray, negative: Bool) -> DecodeResult { + // Must be bytes + case bits { + <<2:3, rest:bits>> -> { + use #(bytes, remainder) <- try(decode_bytestring(rest)) + Ok(#(BigNum(bytes, negative), remainder)) + } + _ -> Error(Malformed) + } +} + fn decode_float(bits: BitArray) -> DecoderResult(IEEEFloat) { case bits { <<25:5, float16:bytes-size(2), rest:bits>> ->