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:
pub fn user_to_json(user: User) -> json.Jsonpub fn user_json_decoder() -> decode.Decoder(User)
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
- Built-in types:
Int,Float,Bool,String,List, tuples - Custom codecs: Types registered via
CustomCodecin config - Annotated types: Types with
//@json_encodeor//@json_decode - Fallback: Unresolved types become function parameters
Types
Configuration for the JSON serialization builder
pub type Config {
Config(custom_codecs: List(CustomCodec))
}
Constructors
-
Config(custom_codecs: List(CustomCodec))
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
-
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), )
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.