···3636 InvalidVarInt(leftover_bits: BitArray, acc: BitArray)
3737 InvalidI64(bits: BitArray)
3838 UnableToDecode(List(decode.DecodeError))
3939+ InvalidLen(len: Int, value_bits: BitArray)
3940}
40414142fn read_fields(
···6869 let read_fn: fn(BitArray) -> ValueResult = case wire_type {
6970 VarInt -> read_varint
7071 I64 -> read_i64
7171- Len -> todo
7272+ Len -> read_len
7273 I32 -> todo
7374 }
7475 use #(value, rest): #(Dynamic, BitArray) <- result.try({
···104105 <<i64:bits-size(64), rest:bytes>> -> Ok(#(i64, rest))
105106 bits -> Error(InvalidI64(bits:))
106107 }
108108+}
109109+110110+fn read_len(bits: BitArray) -> ValueResult {
111111+ // First, read the length of the value
112112+ // It is encoded as a varint immediately after the tag
113113+ use #(len, bits) <- result.try(read_varint(bits))
114114+ let len = bit_array_to_uint(len)
115115+116116+ // Just decoded a uint, so should be safe
117117+ assert len > 0
118118+119119+ use value <- result.try(
120120+ bit_array.slice(from: bits, at: 0, take: len)
121121+ |> result.map_error(fn(_) { InvalidLen(len:, value_bits: bits) }),
122122+ )
123123+ // Assert b/c if the len was too long, it would've errored in the prev slice
124124+ let assert Ok(rest) =
125125+ bit_array.slice(from: bits, at: len, take: bit_array.byte_size(bits) - len)
126126+127127+ Ok(#(value, rest))
107128}
108129109130pub fn decode_uint() -> Decoder(Int) {
+16-1
test/protobuf_decode_gleam_test.gleam
···1313}
14141515fn person_decoder() -> Decoder(Person) {
1616+ let person_inner_decoder = {
1717+ use bits <- decode.then(decode.bit_array)
1818+1919+ let person = decode(from: bits, using: person_decoder())
2020+ case person {
2121+ Ok(person) -> decode.success(person)
2222+ Error(_) ->
2323+ decode.failure(
2424+ Person(id: 0, age: 0, score: 0, self: option.None),
2525+ "Person",
2626+ )
2727+ }
2828+ }
2929+1630 use id <- decode.field(3, decode_u64())
1731 use age <- decode.field(1, decode_uint())
1832 use score <- decode.field(2, decode_uint())
1933 use person <- decode.optional_field(
2034 4,
2135 option.None,
2222- person_decoder() |> decode.map(option.Some),
3636+ decode.optional(person_inner_decoder),
2337 )
3838+2439 decode.success(Person(id:, age:, score:, self: person))
2540}
2641