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
Functions
Basics
Runners
Essential Decoders
Custom Type Decoders
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)
Essential Decoders
Custom Type Decoders
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)
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)