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 decode(codec: Codec(a), a: Dynamic) -> Result(a, String)

Decode a dynamic value

pub fn encode(codec: Codec(a), a: a) -> Dynamic

Encode a type

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