Skip to main content

cratestack_core/
schema.rs

1//! Schema IR — the parsed shape of a `.cstack` file. Every IR node
2//! carries source-span back-pointers so consumers can map errors to
3//! positions in the original text.
4
5pub mod composite_key;
6pub mod model;
7pub mod procedure;
8pub mod selection;
9pub mod view;
10
11use serde::{Deserialize, Serialize};
12
13pub use composite_key::parse_composite_id_attribute;
14pub use model::{
15    Attribute, EnumDecl, EnumVariant, Field, MixinDecl, Model, TypeArity, TypeDecl, TypeRef,
16};
17pub use procedure::{Procedure, ProcedureArg, ProcedureKind};
18pub use selection::SelectionQuery;
19pub use view::{View, ViewSource};
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22pub struct SourceSpan {
23    pub start: usize,
24    pub end: usize,
25    pub line: usize,
26}
27
28/// Wire-shape the schema generates for. Picked once per schema (via
29/// the top-level `transport rest|rpc` directive) so generated servers
30/// and clients only carry one binding's worth of surface.
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
32#[serde(rename_all = "lowercase")]
33pub enum TransportStyle {
34    #[default]
35    Rest,
36    Rpc,
37}
38
39impl TransportStyle {
40    pub const fn as_str(&self) -> &'static str {
41        match self {
42            TransportStyle::Rest => "rest",
43            TransportStyle::Rpc => "rpc",
44        }
45    }
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct Schema {
50    pub datasource: Option<Datasource>,
51    pub auth: Option<AuthBlock>,
52    pub config_blocks: Vec<ConfigBlock>,
53    pub mixins: Vec<MixinDecl>,
54    pub models: Vec<Model>,
55    pub types: Vec<TypeDecl>,
56    pub enums: Vec<EnumDecl>,
57    pub procedures: Vec<Procedure>,
58    #[serde(default)]
59    pub views: Vec<View>,
60    #[serde(default)]
61    pub transport: TransportStyle,
62}
63
64impl Schema {
65    pub fn summary(&self) -> OwnedSchemaSummary {
66        OwnedSchemaSummary {
67            mixins: self.mixins.iter().map(|mixin| mixin.name.clone()).collect(),
68            models: self.models.iter().map(|model| model.name.clone()).collect(),
69            types: self.types.iter().map(|ty| ty.name.clone()).collect(),
70            enums: self
71                .enums
72                .iter()
73                .map(|enum_decl| enum_decl.name.clone())
74                .collect(),
75            procedures: self
76                .procedures
77                .iter()
78                .map(|procedure| procedure.name.clone())
79                .collect(),
80            views: self.views.iter().map(|view| view.name.clone()).collect(),
81        }
82    }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
86pub struct SchemaSummary {
87    pub mixins: &'static [&'static str],
88    pub models: &'static [&'static str],
89    pub types: &'static [&'static str],
90    pub enums: &'static [&'static str],
91    pub procedures: &'static [&'static str],
92    pub views: &'static [&'static str],
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96pub struct OwnedSchemaSummary {
97    pub mixins: Vec<String>,
98    pub models: Vec<String>,
99    pub types: Vec<String>,
100    pub enums: Vec<String>,
101    pub procedures: Vec<String>,
102    #[serde(default)]
103    pub views: Vec<String>,
104}
105
106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
107pub struct Datasource {
108    pub docs: Vec<String>,
109    pub name: String,
110    pub entries: Vec<ConfigEntry>,
111    pub span: SourceSpan,
112}
113
114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
115pub struct AuthBlock {
116    pub docs: Vec<String>,
117    pub name: String,
118    pub fields: Vec<Field>,
119    pub span: SourceSpan,
120}
121
122#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
123pub struct ConfigBlock {
124    pub docs: Vec<String>,
125    pub name: String,
126    pub entries: Vec<String>,
127    pub span: SourceSpan,
128}
129
130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
131pub struct ConfigEntry {
132    pub key: String,
133    pub value: String,
134}