Skip to main content

openapi_nexus/ir/types/
schema.rs

1//! Schema types — the core of the IR's type system.
2
3use indexmap::IndexMap;
4use serde::Serialize;
5
6use super::type_expr::{IrTypeExpr, IrValidation};
7
8/// A named schema in the IR. Every schema has a name (its key in `IrSpec.schemas`),
9/// optional metadata, and a classified kind.
10#[derive(Debug, Clone, Serialize)]
11pub struct IrSchema {
12    pub name: String,
13    pub description: Option<String>,
14    pub deprecated: bool,
15    pub kind: IrSchemaKind,
16    /// Whether this schema originated from `components/schemas` (true) or was
17    /// promoted from an inline definition in operations/responses (false).
18    pub is_component: bool,
19}
20
21/// Pre-classified schema kind. The lowering pass determines this once;
22/// generators match on it directly instead of re-interpreting raw spec fields.
23#[derive(Debug, Clone, Serialize)]
24pub enum IrSchemaKind {
25    /// An object with named properties and optional additional properties.
26    Object(IrObject),
27    /// A typed enumeration.
28    Enum(IrEnum),
29    /// A discriminated union (oneOf with a discriminator field).
30    TaggedUnion(IrTaggedUnion),
31    /// An untagged union (oneOf/anyOf without a discriminator).
32    Union(IrUnion),
33    /// An intersection type (allOf).
34    Intersection(IrIntersection),
35    /// A type alias — wraps a single type expression.
36    Alias(IrTypeExpr),
37}
38
39// ---------------------------------------------------------------------------
40// Object
41// ---------------------------------------------------------------------------
42
43#[derive(Debug, Clone, Serialize)]
44pub struct IrObject {
45    pub properties: IndexMap<String, IrProperty>,
46    pub additional_properties: Option<IrTypeExpr>,
47}
48
49#[derive(Debug, Clone, Serialize)]
50pub struct IrProperty {
51    pub name: String,
52    pub type_expr: IrTypeExpr,
53    pub required: bool,
54    pub nullable: bool,
55    pub description: Option<String>,
56    pub default_value: Option<serde_json::Value>,
57    pub format: Option<String>,
58    pub validation: Option<IrValidation>,
59}
60
61// ---------------------------------------------------------------------------
62// Enum
63// ---------------------------------------------------------------------------
64
65#[derive(Debug, Clone, Serialize)]
66pub struct IrEnum {
67    pub value_type: IrEnumValueType,
68    pub values: Vec<IrEnumValue>,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
72pub enum IrEnumValueType {
73    String,
74    Integer,
75    Number,
76    /// Mixed types (e.g. string + integer).
77    Mixed,
78}
79
80#[derive(Debug, Clone, Serialize)]
81pub struct IrEnumValue {
82    pub value: serde_json::Value,
83    pub description: Option<String>,
84}
85
86// ---------------------------------------------------------------------------
87// Tagged Union (discriminated)
88// ---------------------------------------------------------------------------
89
90#[derive(Debug, Clone, Serialize)]
91pub struct IrTaggedUnion {
92    pub discriminator_field: String,
93    pub tagging: TaggingStyle,
94    pub variants: Vec<IrTaggedVariant>,
95}
96
97#[derive(Debug, Clone, Serialize)]
98pub enum TaggingStyle {
99    /// Tag is a property inside the object itself (`allOf[$ref, { tag: enum }]`).
100    Internal,
101    /// Tag and content are separate fields.
102    Adjacent { content_field: String },
103    /// The key in a wrapping object determines the variant.
104    External,
105}
106
107#[derive(Debug, Clone, Serialize)]
108pub struct IrTaggedVariant {
109    pub discriminator_value: String,
110    pub content_type: IrTypeExpr,
111    pub description: Option<String>,
112}
113
114// ---------------------------------------------------------------------------
115// Union (untagged)
116// ---------------------------------------------------------------------------
117
118#[derive(Debug, Clone, Serialize)]
119pub struct IrUnion {
120    pub members: Vec<IrTypeExpr>,
121    /// Whether the union also includes null (e.g., `anyOf: [string, number, null]`).
122    pub nullable: bool,
123}
124
125// ---------------------------------------------------------------------------
126// Intersection (allOf)
127// ---------------------------------------------------------------------------
128
129#[derive(Debug, Clone, Serialize)]
130pub struct IrIntersection {
131    pub members: Vec<IrTypeExpr>,
132}