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    Grpc,
38}
39
40impl TransportStyle {
41    pub const fn as_str(&self) -> &'static str {
42        match self {
43            TransportStyle::Rest => "rest",
44            TransportStyle::Rpc => "rpc",
45            TransportStyle::Grpc => "grpc",
46        }
47    }
48}
49
50#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51pub struct Schema {
52    pub datasource: Option<Datasource>,
53    pub auth: Option<AuthBlock>,
54    pub config_blocks: Vec<ConfigBlock>,
55    pub mixins: Vec<MixinDecl>,
56    pub models: Vec<Model>,
57    pub types: Vec<TypeDecl>,
58    pub enums: Vec<EnumDecl>,
59    pub procedures: Vec<Procedure>,
60    #[serde(default)]
61    pub views: Vec<View>,
62    #[serde(default)]
63    pub transport: TransportStyle,
64}
65
66impl Schema {
67    pub fn summary(&self) -> OwnedSchemaSummary {
68        OwnedSchemaSummary {
69            mixins: self.mixins.iter().map(|mixin| mixin.name.clone()).collect(),
70            models: self.models.iter().map(|model| model.name.clone()).collect(),
71            types: self.types.iter().map(|ty| ty.name.clone()).collect(),
72            enums: self
73                .enums
74                .iter()
75                .map(|enum_decl| enum_decl.name.clone())
76                .collect(),
77            procedures: self
78                .procedures
79                .iter()
80                .map(|procedure| procedure.name.clone())
81                .collect(),
82            views: self.views.iter().map(|view| view.name.clone()).collect(),
83        }
84    }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct SchemaSummary {
89    pub mixins: &'static [&'static str],
90    pub models: &'static [&'static str],
91    pub types: &'static [&'static str],
92    pub enums: &'static [&'static str],
93    pub procedures: &'static [&'static str],
94    pub views: &'static [&'static str],
95}
96
97#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
98pub struct OwnedSchemaSummary {
99    pub mixins: Vec<String>,
100    pub models: Vec<String>,
101    pub types: Vec<String>,
102    pub enums: Vec<String>,
103    pub procedures: Vec<String>,
104    #[serde(default)]
105    pub views: Vec<String>,
106}
107
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109pub struct Datasource {
110    pub docs: Vec<String>,
111    pub name: String,
112    pub entries: Vec<ConfigEntry>,
113    pub span: SourceSpan,
114}
115
116#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
117pub struct AuthBlock {
118    pub docs: Vec<String>,
119    pub name: String,
120    pub fields: Vec<Field>,
121    pub span: SourceSpan,
122}
123
124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
125pub struct ConfigBlock {
126    pub docs: Vec<String>,
127    pub name: String,
128    pub entries: Vec<String>,
129    pub span: SourceSpan,
130}
131
132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
133pub struct ConfigEntry {
134    pub key: String,
135    pub value: String,
136}