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}