aiken_flat/decoder

Types

Opaque type for decoding from a stored buffer.

Function type shared by all decoders.

Alias

DecoderFn<a> = fn(Decoder) -> (a, Decoder)

Constants

identity_decoder_fn_selector: fn(Int) -> DecoderFn<Data>

identity_decoder_fn_selector_factory: fn(
  Int,
  Scott2<Int, fn(Int) -> DecoderFn<Data>, (Data, Decoder)>,
) -> (Data, Decoder)

Functions

new(bytes: ByteArray) -> Decoder

Initiate a decoder.

Basics

map_decoded(decoder_res: (a, Decoder), map_fn: fn(a) -> b) -> (b, Decoder)

pipe(
  decoder_res: (a, Decoder),
  next_decoder: DecoderFn<b>,
  monoid: fn(a, b) -> c,
) -> (c, Decoder)

map(decoder_fn: DecoderFn<a>, mapping_fn: fn(a) -> b) -> DecoderFn<b>

Runners

unwrap(decoder_res: (a, Decoder)) -> a

Returns the decoded value.

Essential Decoders

integer(self: Decoder) -> (Int, Decoder)

bool(self: Decoder) -> (Bool, Decoder)

u8(self: Decoder) -> (ByteArray, Decoder)

bytes(self: Decoder) -> (ByteArray, Decoder)

filler(self: Decoder) -> Decoder

word(self: Decoder) -> (Int, Decoder)

decode_list_with(
  self: Decoder,
  decoder_func: fn(Decoder) -> (a, Decoder),
) -> (List<a>, Decoder)

bits(self: Decoder, bit_count: Int) -> (Bits, Decoder)

byte_array(self: Decoder) -> (ByteArray, Decoder)

bits8(self: Decoder, n: Int) -> (ByteArray, Decoder)

Decoded value is a single byte.

Custom Type Decoders

make_rec_2(
  f0_decoder: DecoderFn<Data>,
  f1_decoder: DecoderFn<Data>,
) -> DecoderFn<List<Data>>

make_rec_3(
  f0_decoder: DecoderFn<Data>,
  f1_decoder: DecoderFn<Data>,
  f2_decoder: DecoderFn<Data>,
) -> DecoderFn<List<Data>>

make_rec_4(
  f0_decoder: DecoderFn<Data>,
  f1_decoder: DecoderFn<Data>,
  f2_decoder: DecoderFn<Data>,
  f3_decoder: DecoderFn<Data>,
) -> DecoderFn<List<Data>>

make_rec(
  field_count: Int,
  decoder_fn_selector: fn(Int) -> DecoderFn<Data>,
) -> DecoderFn<List<Data>>

Helper for making record type decoders. field_count can’t be negative, but this is not validated (TODO?).

make_sum_2(
  c0_decoders: fn(Int) -> DecoderFn<Data>,
  c0_field_count: Int,
  c1_decoders: fn(Int) -> DecoderFn<Data>,
  c1_field_count: Int,
) -> DecoderFn<Data>

Helper for making decoders for sum types with 2 data constructors, with specified number of arguments each. More performant than using make_sum. The Data in return type is a Constr.

make_sum_3(
  c0_decoders: fn(Int) -> DecoderFn<Data>,
  c0_field_count: Int,
  c1_decoders: fn(Int) -> DecoderFn<Data>,
  c1_field_count: Int,
  c2_decoders: fn(Int) -> DecoderFn<Data>,
  c2_field_count: Int,
) -> DecoderFn<Data>

Helper for making decoders for sum types with 3 data constructors, with specified number of arguments each. More performant than using make_sum. The Data in return type is a Constr.

make_sum_4(
  c0_decoders: fn(Int) -> DecoderFn<Data>,
  c0_field_count: Int,
  c1_decoders: fn(Int) -> DecoderFn<Data>,
  c1_field_count: Int,
  c2_decoders: fn(Int) -> DecoderFn<Data>,
  c2_field_count: Int,
  c3_decoders: fn(Int) -> DecoderFn<Data>,
  c3_field_count: Int,
) -> DecoderFn<Data>

Helper for making decoders for sum types with 4 data constructors, with specified number of arguments each. More performant than using make_sum. The Data in return type is a Constr.

make_sum(
  constr_count: Int,
  decoder_fn_selector_factory: fn(
    Int,
    Scott2<Int, fn(Int) -> DecoderFn<Data>, (Data, Decoder)>,
  ) ->
    (Data, Decoder),
) -> DecoderFn<Data>

Helper function for generating decoders for sum types. The factory is expected to be a function that takes an index, which is the index of the constructor in the subject sum type, and a continuation that provides 2 values: the number of fields for the given tag, and a decoder selector, which itself is a function that given the index of a field, returns a decoder. I’ve used Scott encoding here as a function cannot be put inside a tuple.

An example can be:

pub type Color {
  Abyss
  BlackAndWhite {
    white: Int,
  }
  Colored {
    red: Int,
    green: Int,
    blue: Int,
  }
}

The factory function for this datatype should be:

let color_decoder_factory =
  fn(
    tag: Int,
    return: Scott2<Int, fn(Int) -> DecoderFn<Data>, (Data, Decoder)>,
  ) -> (Data, Decoder) {
    if tag == 0 {
      return(0, identity_decoder_fn_selector)
    } if tag == 1 {
      return(1, fn(_) { integer |> map(builtin.i_data) })
    } if tag == 2 {
      return(3, fn(_) { integer |> map(builtin.i_data) })
    } else {
      fail
    }
  }

And the decoder itself will be:

let color_decoder = make_sum(3, color_decoder_factory)
Search Document