Skip to main content

aion_package/codegen/
model.rs

1//! The intermediate boundary-type model every codegen emitter consumes.
2//!
3//! Types-first (ADR-014, resolved 2026-07-02): the authored source of truth is
4//! the project's Gleam types module `src/<package>_io.gleam`. The interface
5//! front-end ([`super::interface`]) maps the `gleam export package-interface`
6//! JSON for that module into this model; the emitters — the codecs module, the
7//! activity wrappers, the remote worker stubs, the wire-compat golden, and the
8//! emitted `schemas/*.json` artifacts — are all pure functions of it. The model
9//! deliberately mirrors the shapes the generated wire supports: records with
10//! labelled fields, string-wire enums, scalars, lists, and optional fields.
11
12use std::path::PathBuf;
13
14/// A Gleam type reference inside the generated modules.
15#[derive(Clone, Debug, PartialEq)]
16pub(crate) enum GleamType {
17    /// `String`.
18    String,
19    /// `Int`.
20    Int,
21    /// `Float`.
22    Float,
23    /// `Bool`.
24    Bool,
25    /// `List(inner)`.
26    List(Box<GleamType>),
27    /// A reference to another boundary type in the same types module.
28    Named {
29        /// The Gleam type name, e.g. `OrderInput`.
30        type_name: String,
31        /// The derived codec function prefix, e.g. `order_input`.
32        fn_prefix: String,
33    },
34}
35
36/// One record field.
37#[derive(Clone, Debug, PartialEq)]
38pub(crate) struct Field {
39    /// The constructor label; also the JSON wire property name.
40    pub(crate) wire: String,
41    /// Field type (wrapped in `option.Option` in the authored type when not
42    /// required).
43    pub(crate) ty: GleamType,
44    /// Whether the field is required on the wire (`false` for
45    /// `option.Option(t)` fields, which are omitted when `None`).
46    pub(crate) required: bool,
47}
48
49/// A record boundary type: a single-constructor custom type whose parameters
50/// are all labelled.
51#[derive(Clone, Debug, PartialEq)]
52pub(crate) struct RecordDef {
53    /// The authored type (and constructor) name.
54    pub(crate) type_name: String,
55    /// The derived codec function prefix.
56    pub(crate) fn_prefix: String,
57    /// Fields in declared constructor-parameter order.
58    pub(crate) fields: Vec<Field>,
59}
60
61/// One enum constructor with its derived wire string.
62#[derive(Clone, Debug, PartialEq)]
63pub(crate) struct EnumVariant {
64    /// The authored constructor name, e.g. `InputPlacementLocal`.
65    pub(crate) constructor: String,
66    /// The canonical wire string: `snake_case` of the constructor with the
67    /// enum type-name prefix stripped (`InputPlacementLocal` → `local`).
68    pub(crate) wire: String,
69}
70
71/// An enum boundary type: a multi-constructor custom type whose constructors
72/// all carry zero parameters, encoded as its wire string.
73#[derive(Clone, Debug, PartialEq)]
74pub(crate) struct EnumDef {
75    /// The authored type name.
76    pub(crate) type_name: String,
77    /// The derived codec function prefix.
78    pub(crate) fn_prefix: String,
79    /// Variants in declared constructor order.
80    pub(crate) variants: Vec<EnumVariant>,
81}
82
83/// A boundary type definition.
84#[derive(Clone, Debug, PartialEq)]
85pub(crate) enum TypeDef {
86    /// A record (single labelled constructor).
87    Record(RecordDef),
88    /// An enum (multiple zero-arity constructors).
89    Enum(EnumDef),
90}
91
92impl TypeDef {
93    /// The type name of this definition.
94    pub(crate) fn type_name(&self) -> &str {
95        match self {
96            TypeDef::Record(record) => &record.type_name,
97            TypeDef::Enum(definition) => &definition.type_name,
98        }
99    }
100}
101
102/// One public type of the authored types module, with everything the emitters
103/// need: its emitted schema path, its own definition, and the definitions of
104/// every sibling type it references transitively.
105#[derive(Clone, Debug, PartialEq)]
106pub struct BoundaryType {
107    /// The emitted schema artifact path, relative to the project root
108    /// (`schemas/<stem>.json`).
109    pub(crate) file: PathBuf,
110    /// The `snake_case` stem derived from the type name (`order_input`).
111    pub(crate) stem: String,
112    /// The type itself (always [`GleamType::Named`]).
113    pub(crate) root: GleamType,
114    /// This type's definition first, then every sibling definition it
115    /// references transitively, in depth-first field order.
116    pub(crate) defs: Vec<TypeDef>,
117}