Skip to main content

tempest_engine/catalog/
schema.rs

1use std::collections::{BTreeMap, HashSet};
2
3use derive_more::{Deref, Display};
4use serde::{Deserialize, Serialize};
5use tempest_core::tempest_str::TempestStr;
6
7use crate::types::TempestType;
8
9#[derive(Debug, Clone)]
10pub(crate) struct FlatField {
11    pub name: TempestStr<'static>,
12    pub ty: TempestType,
13    /// For Enum fields: the concrete generic args at this instantiation site.
14    /// Used by the row decoder to resolve payload field types.
15    pub type_args: Vec<TypeExpr>,
16}
17
18#[derive(
19    Debug,
20    Default,
21    Display,
22    Clone,
23    Copy,
24    PartialEq,
25    Eq,
26    PartialOrd,
27    Ord,
28    Hash,
29    Deref,
30    Serialize,
31    Deserialize,
32)]
33pub struct FieldId(pub u32);
34
35#[derive(
36    Debug,
37    Default,
38    Display,
39    Clone,
40    Copy,
41    PartialEq,
42    Eq,
43    PartialOrd,
44    Ord,
45    Hash,
46    Deref,
47    Serialize,
48    Deserialize,
49)]
50pub struct TypeId(pub u32);
51
52#[derive(
53    Debug,
54    Default,
55    Display,
56    Clone,
57    Copy,
58    PartialEq,
59    Eq,
60    PartialOrd,
61    Ord,
62    Hash,
63    Deref,
64    Serialize,
65    Deserialize,
66)]
67pub struct TableId(pub u32);
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub enum TypeExpr {
71    Primitive(TempestType),
72    Ref(TypeId, Vec<TypeExpr>),
73    GenericParam(u32),
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct FieldDef {
78    /// Name of this column.
79    pub name: TempestStr<'static>,
80    /// Type of this column.
81    pub ty: TypeExpr,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct StructSchema {
86    /// The ID of the database this struct is scoped to, or `None` for global built-in types.
87    pub database_id: Option<DatabaseId>,
88    /// The scope-unique name of this struct.
89    pub name: TempestStr<'static>,
90    /// The generic parameters this struct takes in.
91    pub generic_params: Vec<TempestStr<'static>>,
92    /// The fields of this struct.
93    pub fields: BTreeMap<FieldId, FieldDef>,
94}
95
96#[derive(
97    Debug,
98    Default,
99    Display,
100    Clone,
101    Copy,
102    PartialEq,
103    Eq,
104    PartialOrd,
105    Ord,
106    Hash,
107    Deref,
108    Serialize,
109    Deserialize,
110)]
111pub struct VariantId(pub u32);
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct EnumVariantDef {
115    pub name: TempestStr<'static>,
116    /// Field types for tuple variants (empty for unit variants).
117    pub fields: Vec<TypeExpr>,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct EnumSchema {
122    /// The ID of the database this enum is scoped to, or `None` for global built-in types.
123    pub database_id: Option<DatabaseId>,
124    pub name: TempestStr<'static>,
125    pub generic_params: Vec<TempestStr<'static>>,
126    pub variants: BTreeMap<VariantId, EnumVariantDef>,
127}
128
129/// A catalog type — either a struct or an enum.
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub enum TypeSchema {
132    Struct(StructSchema),
133    Enum(EnumSchema),
134}
135
136impl TypeSchema {
137    pub fn database_id(&self) -> Option<DatabaseId> {
138        match self {
139            Self::Struct(s) => s.database_id,
140            Self::Enum(e) => e.database_id,
141        }
142    }
143
144    pub fn name(&self) -> &TempestStr<'static> {
145        match self {
146            Self::Struct(s) => &s.name,
147            Self::Enum(e) => &e.name,
148        }
149    }
150
151    pub fn as_struct(&self) -> Option<&StructSchema> {
152        if let Self::Struct(s) = self { Some(s) } else { None }
153    }
154
155    pub fn as_enum(&self) -> Option<&EnumSchema> {
156        if let Self::Enum(e) = self { Some(e) } else { None }
157    }
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct TableSchema {
162    /// The unique ID of the database this table belongs to.
163    pub database_id: DatabaseId,
164    /// Name of this table.
165    pub name: TempestStr<'static>,
166    /// The ID of the [`TypeSchema`] that this table has.
167    pub type_id: TypeId,
168    /// The generic arguments supplied to this struct.
169    pub generic_args: Vec<TypeExpr>,
170    /// Paths of field IDs for each primary key column, most significant first.
171    /// Each inner Vec is a root-to-leaf path through the type hierarchy.
172    /// e.g. `[[FieldId(1), FieldId(0)]]` means: top-level field 1, then nested field 0 within it.
173    pub primary_key: Vec<Vec<FieldId>>,
174}
175
176#[derive(
177    Debug,
178    Default,
179    Display,
180    Clone,
181    Copy,
182    PartialEq,
183    Eq,
184    PartialOrd,
185    Ord,
186    Hash,
187    Deref,
188    Serialize,
189    Deserialize,
190)]
191pub struct DatabaseId(pub u32);
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct DatabaseSchema {
195    /// Name of this dtabase.
196    pub name: TempestStr<'static>,
197    /// The tables this database contains.
198    pub tables: HashSet<TableId>,
199    /// The types this database contains.
200    pub types: HashSet<TypeId>,
201}
202
203impl DatabaseSchema {
204    pub(crate) fn new(name: TempestStr<'static>) -> Self {
205        Self {
206            name,
207            tables: HashSet::new(),
208            types: HashSet::new(),
209        }
210    }
211}