1pub mod composite_key;
6pub mod composite_unique;
7mod field_list;
8pub mod index_attribute;
9pub mod model;
10pub mod procedure;
11pub mod selection;
12pub mod view;
13
14use std::collections::BTreeSet;
15
16use serde::{Deserialize, Serialize};
17
18pub use composite_key::parse_composite_id_attribute;
19pub use composite_unique::parse_composite_unique_attribute;
20pub use index_attribute::{ParsedIndexAttribute, parse_index_attribute};
21pub use model::{
22 Attribute, EnumDecl, EnumVariant, Field, MixinDecl, Model, TypeArity, TypeDecl, TypeRef,
23};
24pub use procedure::{Procedure, ProcedureArg, ProcedureKind};
25pub use selection::SelectionQuery;
26pub use view::{View, ViewSource};
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
29pub struct SourceSpan {
30 pub start: usize,
31 pub end: usize,
32 pub line: usize,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
39#[serde(rename_all = "lowercase")]
40pub enum TransportStyle {
41 #[default]
42 Rest,
43 Rpc,
44 Grpc,
45}
46
47impl TransportStyle {
48 pub const fn as_str(&self) -> &'static str {
49 match self {
50 TransportStyle::Rest => "rest",
51 TransportStyle::Rpc => "rpc",
52 TransportStyle::Grpc => "grpc",
53 }
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
67#[serde(rename_all = "snake_case")]
68pub enum ExtensionKind {
69 RateLimit,
70 Pgvector,
71}
72
73impl ExtensionKind {
74 pub const ALL: [ExtensionKind; 2] = [ExtensionKind::RateLimit, ExtensionKind::Pgvector];
77
78 pub const fn as_str(&self) -> &'static str {
79 match self {
80 ExtensionKind::RateLimit => "rate_limit",
81 ExtensionKind::Pgvector => "pgvector",
82 }
83 }
84
85 pub fn parse_name(name: &str) -> Option<Self> {
89 ExtensionKind::ALL
90 .into_iter()
91 .find(|kind| kind.as_str() == name)
92 }
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub struct Schema {
97 pub datasource: Option<Datasource>,
98 pub auth: Option<AuthBlock>,
99 pub config_blocks: Vec<ConfigBlock>,
100 pub mixins: Vec<MixinDecl>,
101 pub models: Vec<Model>,
102 pub types: Vec<TypeDecl>,
103 pub enums: Vec<EnumDecl>,
104 pub procedures: Vec<Procedure>,
105 #[serde(default)]
106 pub views: Vec<View>,
107 #[serde(default)]
108 pub transport: TransportStyle,
109 #[serde(default)]
113 pub declared_extensions: BTreeSet<ExtensionKind>,
114}
115
116impl Schema {
117 pub fn summary(&self) -> OwnedSchemaSummary {
118 OwnedSchemaSummary {
119 mixins: self.mixins.iter().map(|mixin| mixin.name.clone()).collect(),
120 models: self.models.iter().map(|model| model.name.clone()).collect(),
121 types: self.types.iter().map(|ty| ty.name.clone()).collect(),
122 enums: self
123 .enums
124 .iter()
125 .map(|enum_decl| enum_decl.name.clone())
126 .collect(),
127 procedures: self
128 .procedures
129 .iter()
130 .map(|procedure| procedure.name.clone())
131 .collect(),
132 views: self.views.iter().map(|view| view.name.clone()).collect(),
133 }
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Eq)]
138pub struct SchemaSummary {
139 pub mixins: &'static [&'static str],
140 pub models: &'static [&'static str],
141 pub types: &'static [&'static str],
142 pub enums: &'static [&'static str],
143 pub procedures: &'static [&'static str],
144 pub views: &'static [&'static str],
145}
146
147#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
148pub struct OwnedSchemaSummary {
149 pub mixins: Vec<String>,
150 pub models: Vec<String>,
151 pub types: Vec<String>,
152 pub enums: Vec<String>,
153 pub procedures: Vec<String>,
154 #[serde(default)]
155 pub views: Vec<String>,
156}
157
158#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
159pub struct Datasource {
160 pub docs: Vec<String>,
161 pub name: String,
162 pub entries: Vec<ConfigEntry>,
163 pub span: SourceSpan,
164}
165
166#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
167pub struct AuthBlock {
168 pub docs: Vec<String>,
169 pub name: String,
170 pub fields: Vec<Field>,
171 pub span: SourceSpan,
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
175pub struct ConfigBlock {
176 pub docs: Vec<String>,
177 pub name: String,
178 pub entries: Vec<String>,
179 pub span: SourceSpan,
180}
181
182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
183pub struct ConfigEntry {
184 pub key: String,
185 pub value: String,
186}