codec
Types
pub type Codec(a) {
Codec(encoder: Encoder(a), decoder: Decoder(a))
}
Constructors
-
Codec(encoder: Encoder(a), decoder: Decoder(a))
Partial Codec for creating a custom type codec
pub type CustomCodec(match, v) {
CustomCodec(match: match, decoders: Map(String, Decoder(v)))
}
Constructors
-
CustomCodec(match: match, decoders: Map(String, Decoder(v)))
A codec for a record field
pub type RecordFieldCodec(input, output) {
RecordFieldCodec(
field: String,
encoder: Encoder(input),
decoder: Decoder(output),
)
}
Constructors
-
RecordFieldCodec( field: String, encoder: Encoder(input), decoder: Decoder(output), )
Type used for specifiying a variant field
pub type VariantFieldCodec(field) {
VariantFieldCodec(
field: String,
encoder: Encoder(field),
decoder: Decoder(field),
)
}
Constructors
-
VariantFieldCodec( field: String, encoder: Encoder(field), decoder: Decoder(field), )
Functions
pub fn bool() -> Codec(Bool)
Create a codec for Bool
Example
let c = codec.bool()
let value = dynamic.from(True)
codec.decode(c, value)
> Ok(True)
pub fn build(
encoder: fn(a) -> Dynamic,
decoder: fn(Dynamic) -> Result(a, String),
) -> Codec(a)
pub fn custom(match: a) -> CustomCodec(a, b)
Create a codec for custom type
##Example
type Process {
Pending
Active(Int, String)
Done(answer: Float)
}
let c = codec.custom(
fn(
encode_pending,
encode_active,
encode_done,
value
) {
case value {
Pending ->
encode_pending()
Active(i, s) ->
encode_active(i, s)
Done(r) ->
encode_done(r)
}
}
|> function.curry4
)
|> codec.variant0("Pending", Pending)
|> codec.variant2(
"Active",
Active,
codec.variant_field("count", codec.int()),
codec.variant_field("name", codec.string())
)
|> codec.variant1(
"Done",
Done,
codec.variant_field("answer", codec.float())
)
|> codec.finish_custom()
let active = Active(1, "x")
let value = codec.encode(c, active)
pub fn finish_custom(
c: CustomCodec(fn(a) -> Dynamic, a),
) -> Codec(a)
Finish building a custom type codec
pub fn float() -> Codec(Float)
Create a codec for Float
Example
let c = codec.float()
let value = dynamic.from(3.1516)
codec.decode(c, value)
> Ok(3.1516)
pub fn int() -> Codec(Int)
Create a codec for Int
Example
let c = codec.int()
let value = dynamic.from(12)
codec.decode(c, value)
> Ok(12)
pub fn list(codec: Codec(a)) -> Codec(List(a))
Create a codec for List
Example
let c = codec.list(codec.int())
let value = dynamic.from([1, 2, 3])
codec.decode(c, value)
> Ok([1, 2, 3])
pub fn map(
codec_key: Codec(a),
codec_value: Codec(b),
) -> Codec(Map(a, b))
Create a codec for a Map
Example
let c = codec.map(
codec.string(),
codec.int(),
)
let dict = [ #("a", 1) ] |> map.from_list
codec.encode(c, dict)
pub fn option(codec: Codec(a)) -> Codec(Option(a))
Create a codec for Option
A Some is encoded as just the value e.g. Some(“Hello”) becomes “Hello” A None is encoded as a :null atom in Elixir
Example
let c = codec.option(codec.string())
let value = codec.encode(c, Some("Hello"))
codec.decode(c, value)
> Ok(Some("Hello"))
pub fn record1(
type_name: String,
constructor: fn(a) -> b,
codec1: RecordFieldCodec(b, a),
) -> Codec(b)
Create a codec for a record (a custom type with only one constructor) with one field
Example
type Person{
Person(name: String)
}
let c = codec.record1(
"Person",
Person,
codec.record_field(
"name",
fn(p: Person) { p.name },
codec.string()
),
)
let sam = Person("Sam")
let value = codec.encode(c, sam)
The record will be encoded as a map
%{ "__type__" => "Person", "name" => "Sam"}
codec.decode(c, value)
> Ok(sam)
pub fn record2(
type_name: String,
constructor: fn(a, b) -> c,
codec1: RecordFieldCodec(c, a),
codec2: RecordFieldCodec(c, b),
) -> Codec(c)
Create a codec for a record with two fields
Example
type Pet{
Pet(age: Int, name: String)
}
let c = codec.record2(
"Pet",
Pet,
codec.record_field(
"age",
fn(p: Pet) { p.age },
codec.int()
),
codec.record_field(
"name",
fn(p: Pet) { p.name },
codec.string()
),
)
let pet = Pet(3, "Fido")
codec.encode(c, pet)
pub fn record_field(
name: String,
get: fn(a) -> b,
field_codec: Codec(b),
) -> RecordFieldCodec(a, b)
Build a RecordFieldCodec To be used with record1, record2, …
Example
codec.record_field(
"age",
fn(p: Pet) { p.age },
codec.int()
)
pub fn string() -> Codec(String)
Create a codec for String
Example
let c = codec.string()
let value = dynamic.from("Hello")
codec.decode(c, value)
> Ok("Hello")
pub fn tuple2(
codec_a: Codec(a),
codec_b: Codec(b),
) -> Codec(#(a, b))
Create a codec for a tuple of two elements
Example
let c = codec.tuple2(codec.string(), codec.int())
let value = codec.encode(c, #("a", 1))
codec.decode(c, value)
> Ok(#("a", 1))
pub fn variant0(
c: CustomCodec(fn(fn() -> Dynamic) -> a, b),
type_name: String,
constructor: b,
) -> CustomCodec(a, b)
Create a codec for variant with no fields
See documentation for custom
pub fn variant1(
c: CustomCodec(fn(fn(a) -> Dynamic) -> b, c),
type_name: String,
constructor: fn(a) -> c,
codec1: VariantFieldCodec(a),
) -> CustomCodec(b, c)
Create a codec for variant with one field
pub fn variant2(
c: CustomCodec(fn(fn(a, b) -> Dynamic) -> c, d),
type_name: String,
constructor: fn(a, b) -> d,
codec1: VariantFieldCodec(a),
codec2: VariantFieldCodec(b),
) -> CustomCodec(c, d)
Create a codec for variant with two fields
pub fn variant3(
c: CustomCodec(fn(fn(a, b, c) -> Dynamic) -> d, e),
type_name: String,
constructor: fn(a, b, c) -> e,
codec1: VariantFieldCodec(a),
codec2: VariantFieldCodec(b),
codec3: VariantFieldCodec(c),
) -> CustomCodec(d, e)
Create a codec for variant with three fields
pub fn variant_field(
field_name: String,
field_codec: Codec(a),
) -> VariantFieldCodec(a)
Used when building a custom type codec
See documentation for custom