···7788import internal/util
99import protobuf_decode_gleam.{
1010- type BytePos, type DecodeResult, type ValueParser, Parsed, UnableToDecode,
1111- parse,
1010+ type BytePos, type DecodeResult, type ValueParser, Parsed, parse, read_varint,
1211}
13121413/// Decode a repeated field that may be either packed or expanded.
1515-/// If the field is known ahead of time to be expanded, use the stdlib's
1616-/// `decode.list()`.
1414+///
1515+/// If it is impossible for a field to be expanded (ie because it is encoded as
1616+/// a `LEN`) and therefore there is no `ValueParser` for it, then use the
1717+/// stdlib's `decode.list()` instead.
1718pub fn multiple(
1819 of decoder: Decoder(t),
1920 using parser: ValueParser,
2021) -> Decoder(List(t)) {
2121- use values <- decode.then(
2222- decode.one_of(decode.list(of: decoder), or: [
2323- packed_values(of: decoder, using: parser),
2424- ]),
2525- )
2222+ use values <- decode.then(packed_values(of: decoder, using: parser))
2623 values |> decode.success
2724}
2825···3027 of decoder: Decoder(t),
3128 using parser: ValueParser,
3229) -> Decoder(List(t)) {
3333- use bits <- decode.then(decode.bit_array)
3030+ use bits <- decode.then(decode.list(of: decode.bit_array))
3131+ let bits =
3232+ list.fold(bits, <<>>, fn(acc, elem) { bit_array.concat([acc, elem]) })
34333534 let values = {
3635 use values <- result.try(unpack_bits(bits, [], at: 0, using: parser))
3736 values
3837 |> list.map(dynamic.bit_array)
3938 |> list.try_map(fn(value) { decode.run(value, decoder) })
4040- |> result.map_error(UnableToDecode)
3939+ |> result.map_error(protobuf_decode_gleam.UnableToDecode)
4140 }
42414342 case values {
···6160 }
6261}
63626363+/// Expects a single value from a list. Panics if the list is empty.
6464fn single(of decoder: Decoder(t)) -> Decoder(t) {
6565 use values <- decode.then(decode.list(of: decoder))
6666···95959696pub fn uint() -> Decoder(Int) {
9797 use bits <- decode.then(single_or_raw(decode.bit_array))
9898- util.bit_array_to_uint(bits) |> decode.success
9898+ use bits <- decode.then(case read_varint(bits, 0) {
9999+ Ok(Parsed(value:, rest: <<>>, pos: _)) -> decode.success(value)
100100+ _ -> decode.failure(<<>>, "uint")
101101+ })
102102+ bits |> util.bit_array_to_uint |> decode.success
99103}
100104101105pub fn fixed(size: Int) -> Decoder(Int) {
+39-14
src/protobuf_decode_gleam.gleam
···5151 }
5252}
53535454-fn repeated_to_list(fields: List(Field)) -> dict.Dict(Dynamic, Dynamic) {
5454+fn repeated_to_list(reversed_fields: List(Field)) -> dict.Dict(Dynamic, Dynamic) {
5555 let fields = {
5656 // Every field is a list of values for two reasons:
5757 // a) expanded repeated values are encoded as repeated fields
···6060 // fields are repeating, it parses all fields as a list and then the
6161 // decoders will handle choosing which value(s) to keep.
6262 let acc: dict.Dict(Dynamic, List(Dynamic)) = dict.new()
6363- use fields, Field(key:, value:) <- list.fold(over: fields, from: acc)
6363+ use fields, Field(key:, value:) <- list.fold(
6464+ over: reversed_fields,
6565+ from: acc,
6666+ )
64676568 use existing_values <- dict.upsert(in: fields, update: key)
6669 let existing_values = option.unwrap(existing_values, or: [])
7070+ // The repeated values were previously reversed, now being reversed again
6771 [value, ..existing_values]
6872 }
69737070- // The repeated values must be in order, so un-reverse them here
7171- dict.map_values(in: fields, with: fn(_key, field) {
7272- field |> list.reverse |> dynamic.list
7373- })
7474+ dict.map_values(in: fields, with: fn(_key, field) { field |> dynamic.list })
7475}
75767677pub type DecodeResult(t) =
···9293 Field(key: Dynamic, value: Dynamic)
9394}
94959595-fn wire_type_read_fn(ty: WireType) -> ValueParser {
9696+fn wire_type_consume_fn(ty: WireType) -> ValueParser {
9697 case ty {
9797- wire_type.VarInt -> read_varint
9898+ wire_type.VarInt -> consume_varint
9899 wire_type.I64 -> read_fixed(64)
99100 wire_type.Len -> read_len
100101 wire_type.I32 -> read_fixed(32)
···123124 UnknownWireType(wire_type, pos: tag_pos),
124125 ))
125126126126- let read_fn = wire_type_read_fn(wire_type)
127127- use value: Parsed(Dynamic) <- result.try({
128128- use value <- result.map(read_fn(bits, pos))
129129- parsed_map(value, dynamic.bit_array)
130130- })
127127+ let consume = wire_type_consume_fn(wire_type)
128128+ use value: Parsed(Dynamic) <- result.try(
129129+ consume(bits, pos) |> result.map(parsed_map(_, dynamic.bit_array)),
130130+ )
131131132132 let field =
133133 parsed_map(value, fn(value) { Field(key: dynamic.int(field_id), value:) })
···141141pub type ValueParser =
142142 fn(BitArray, BytePos) -> ValueResult
143143144144+pub fn consume_varint(bits: BitArray, pos: BytePos) -> ValueResult {
145145+ consume_varint_acc(bits, <<>>, pos)
146146+}
147147+148148+fn consume_varint_acc(
149149+ bits: BitArray,
150150+ acc: BitArray,
151151+ pos: BytePos,
152152+) -> ValueResult {
153153+ case bits {
154154+ <<0:size(1), n:bits-size(7), rest:bytes>> -> {
155155+ let bit = <<0:size(1), n:bits>>
156156+ let acc = bit_array.concat([acc, bit])
157157+ Ok(Parsed(value: acc, rest:, pos: pos + 1))
158158+ }
159159+ <<1:size(1), n:bits-size(7), rest:bytes>> -> {
160160+ let bit = <<1:size(1), n:bits>>
161161+ consume_varint_acc(rest, bit_array.concat([acc, bit]), pos + 1)
162162+ }
163163+ bits -> Error(InvalidVarInt(leftover_bits: bits, acc:, pos:))
164164+ }
165165+}
166166+144167pub fn read_varint(bits: BitArray, pos: BytePos) -> ValueResult {
145168 read_varint_acc(bits, <<>>, pos)
146169}
···153176 }
154177 <<1:size(1), n:bits-size(7), rest:bytes>> ->
155178 read_varint_acc(rest, bit_array.concat([n, acc]), pos + 1)
156156- bits -> Error(InvalidVarInt(leftover_bits: bits, acc:, pos:))
179179+ bits -> {
180180+ Error(InvalidVarInt(leftover_bits: bits, acc:, pos:))
181181+ }
157182 }
158183}
159184