sara/json

JSON Serialization Code Generator

This module provides a builder that automatically generates JSON encoding and decoding functions for Gleam custom types annotated with //@json_encode and/or //@json_decode.

Basic Usage

Annotate your types:

//@json_encode
//@json_decode
pub type User {
  User(name: String, age: Int)
}

This generates a companion *_json.gleam file containing:

Custom Codecs

For types requiring special serialization logic, provide a CustomCodec:

json.json_serializable_builder(
  json.Config([
    json.CustomCodec(
      type_name: "Timestamp",
      module_path: "gleam/time/timestamp",
      encode: fn(_, _, variable, _, _) {
        json.GeneratedCode(
          "json.string(timestamp.to_rfc3339(" <> variable <> ", calendar.utc_offset))",
          ["gleam/time/calendar", "gleam/time/timestamp"],
          [],
        )
      },
      decode: fn(_, _, _, _) {
        json.GeneratedCode(
          "{
  use date <- decode.then(decode.string)
  case timestamp.parse_rfc3339(date) {
    Ok(timestamp) -> decode.success(timestamp)
    Error(_) -> decode.failure(timestamp.system_time(), \"Timestamp\")
  }
}",
          ["gleam/time/calendar", "gleam/time/timestamp"],
          [],
        )
      },
      zero: fn(_, _, _, _) {
        Ok(json.GeneratedCode("timestamp.system_time()", ["gleam/time/timestamp"], []))
      },
    ),
  ]),
)

Codec Resolution Order

  1. Built-in types: Int, Float, Bool, String, List, tuples
  2. Custom codecs: Types registered via CustomCodec in config
  3. Annotated types: Types with //@json_encode or //@json_decode
  4. Fallback: Unresolved types become function parameters

Types

Configuration for the JSON serialization builder

pub type Config {
  Config(custom_codecs: List(CustomCodec))
}

Constructors

Allows you to define how a specific type should be serialized to JSON, deserialized from JSON, and what its zero/default value should be. Note: the zero value is only use for decode failure of variants type

pub type CustomCodec {
  CustomCodec(
    type_name: String,
    module_path: String,
    encode: fn(
      context.BuildContext,
      glance.Type,
      String,
      module.Module,
      module.Module,
    ) -> GeneratedCode,
    decode: fn(
      context.BuildContext,
      glance.Type,
      module.Module,
      module.Module,
    ) -> GeneratedCode,
    zero: fn(
      context.BuildContext,
      glance.Type,
      module.Module,
      module.Module,
    ) -> Result(GeneratedCode, Nil),
  )
}

Constructors

Represents generated code with its dependencies and required arguments

Used internally to track code generation, required imports, and custom function parameters needed for encoding/decoding operations.

pub type GeneratedCode {
  GeneratedCode(
    code: String,
    imports: List(String),
    arguments: List(#(String, String)),
  )
}

Constructors

  • GeneratedCode(
      code: String,
      imports: List(String),
      arguments: List(#(String, String)),
    )

Values

pub fn json_serializable_builder(config: Config) -> core.Builder

Creates a builder that generates JSON encoding and decoding functions.

Search Document