json/blueprint/codegen

Codec definitions that run as a Codec(a) and compile to a Gleam module with the same encoder, decoders and schema.

This module is included in json_blueprint. Use it in an explicit build task or a test. A Definition(a) is built from the same shapes as json/blueprint/codec; mappings to your own types name their functions (named_mapping, enum_variant) because the generated source must call them. runtime returns the definition’s codec. compile returns a GeneratedModule whose content the caller writes under src/, formats with gleam format, and keeps fresh with a test that compiles again and compares. A definition mistake, such as a property named twice, is a CompileError.

Generated modules call json/blueprint/internal/generated, whose names json_blueprint keeps stable within a major version. They decode text with the shared strict parser and decode its retained native evidence directly. The codec accessor also retains the specialized text encoder and schema. decode_<name>_json_native uses gleam/json instead, returns json.DecodeError, and rejects text above 1 MiB before parsing.

import json/blueprint/codec
import json/blueprint/codegen

pub fn names_definition() -> codegen.Definition(List(String)) {
  codegen.list(codegen.string())
}

pub fn example() {
  let assert Ok(["a", "b"]) =
    codec.decode_json(codegen.runtime(names_definition()), "[\"a\",\"b\"]")
  // In a build task: write `content` to "src/" <> path.
  let assert Ok(codegen.GeneratedModule(path:, content:, fingerprint: _)) =
    codegen.compile("generated/names_codec", "names", names_definition())
  #(path, content)
}

Types

pub type CompileError {
  InvalidCodecName(String, String)
  InvalidModulePath(String, String)
  InvalidTypeReference(String)
  MissingTypeImport(String)
  InvalidFunctionReference(String)
  ConflictingImportAlias(String, String, String)
  DuplicateSchemaAccessor(String)
  UnsupportedSchemaConstructor(List(String), String)
  NativeNumberUnsupported
  InvalidDefinition(codec.DefinitionError)
  UnknownSchema(String)
}

Constructors

  • InvalidCodecName(String, String)
  • InvalidModulePath(String, String)
  • InvalidTypeReference(String)
  • MissingTypeImport(String)
  • InvalidFunctionReference(String)
  • ConflictingImportAlias(String, String, String)
  • DuplicateSchemaAccessor(String)
  • UnsupportedSchemaConstructor(List(String), String)
  • NativeNumberUnsupported
  • InvalidDefinition(codec.DefinitionError)
  • UnknownSchema(String)
pub opaque type Definition(a)
pub opaque type EnumVariant(a)
pub type GeneratedModule {
  GeneratedModule(
    path: String,
    content: String,
    fingerprint: String,
  )
}

Constructors

  • GeneratedModule(
      path: String,
      content: String,
      fingerprint: String,
    )
pub opaque type Mapping(a, b)

The properties of an object definition whose record type is r, with values of type a. combine pairs them; object closes them.

pub opaque type Properties(r, a)

Values

pub fn bool() -> Definition(Bool)
pub fn combine(
  left: Properties(r, a),
  right: Properties(r, b),
) -> Properties(r, #(a, b))

Both groups of properties, as a pair. A name in both groups is a definition mistake that compile reports.

pub fn compile(
  module_path: String,
  name: String,
  definition: Definition(a),
) -> Result(GeneratedModule, CompileError)

Compile one canonical typed definition into Blueprint Value operations, gleam/json-native text operations, a schema, and an interchangeable Codec. Ordinary text decoding uses Blueprint’s strict parser. An explicitly named native decoder remains available for callers needing gleam/json parsing.

pub fn describe(
  definition: Definition(a),
  description: String,
) -> Definition(a)

Add the same schema description to runtime and generated codecs.

pub fn enum_variant(
  label: String,
  value: a,
  reference: String,
) -> Result(EnumVariant(a), CompileError)
pub fn imap(
  inner: Definition(a),
  output_type: String,
  mapping: Mapping(a, b),
) -> Result(Definition(b), CompileError)
pub fn int() -> Definition(Int)
pub fn integer_between(min: Int, max: Int) -> Definition(Int)

An integer from min to max inclusive. Reversed bounds are a definition mistake that compile reports.

pub fn list(inner: Definition(a)) -> Definition(List(a))
pub fn named_mapping(
  from: fn(a) -> b,
  from_reference: String,
  to: fn(b) -> a,
  to_reference: String,
) -> Result(Mapping(a, b), CompileError)
pub fn nullable(
  inner: Definition(a),
) -> Definition(option.Option(a))
pub fn object(properties: Properties(a, a)) -> Definition(a)

A closed object of the properties.

pub fn optional(
  name: String,
  inner: Definition(a),
) -> Properties(r, option.Option(a))

An optional property: absent is None. With a nullable inner definition, absent, null and a value are None, Some(None) and Some(Some(x)).

pub fn pair(
  left: Definition(a),
  right: Definition(b),
) -> Definition(#(a, b))
pub fn required(
  name: String,
  inner: Definition(a),
) -> Properties(r, a)

A required property.

pub fn runtime(definition: Definition(a)) -> codec.Codec(a)
pub fn string() -> Definition(String)
pub fn string_enum(
  type_name: String,
  variants: List(EnumVariant(a)),
) -> Result(Definition(a), CompileError)
✨ Search Document