Skip to main content

cratestack_core/schema/
model.rs

1//! Model / mixin / type / enum / field IR nodes parsed out of a
2//! `.cstack` file. Every IR node carries [`SourceSpan`] back-pointers
3//! so consumers (parser, LSP, generators) can map errors to source
4//! positions.
5
6use serde::{Deserialize, Serialize};
7
8use super::SourceSpan;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11pub struct Model {
12    pub docs: Vec<String>,
13    pub name: String,
14    pub name_span: SourceSpan,
15    pub fields: Vec<Field>,
16    pub attributes: Vec<Attribute>,
17    pub span: SourceSpan,
18}
19
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct MixinDecl {
22    pub docs: Vec<String>,
23    pub name: String,
24    pub name_span: SourceSpan,
25    pub fields: Vec<Field>,
26    pub span: SourceSpan,
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct TypeDecl {
31    pub docs: Vec<String>,
32    pub name: String,
33    pub name_span: SourceSpan,
34    pub fields: Vec<Field>,
35    pub span: SourceSpan,
36}
37
38#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
39pub struct EnumDecl {
40    pub docs: Vec<String>,
41    pub name: String,
42    pub name_span: SourceSpan,
43    pub variants: Vec<EnumVariant>,
44    pub span: SourceSpan,
45}
46
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48pub struct EnumVariant {
49    pub docs: Vec<String>,
50    pub name: String,
51    pub span: SourceSpan,
52}
53
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55pub struct Field {
56    pub docs: Vec<String>,
57    pub name: String,
58    pub name_span: SourceSpan,
59    pub ty: TypeRef,
60    pub attributes: Vec<Attribute>,
61    pub span: SourceSpan,
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
65pub struct TypeRef {
66    pub name: String,
67    pub name_span: SourceSpan,
68    pub arity: TypeArity,
69    pub generic_args: Vec<TypeRef>,
70}
71
72impl TypeRef {
73    pub fn is_page(&self) -> bool {
74        self.name == "Page"
75    }
76
77    pub fn page_item(&self) -> Option<&TypeRef> {
78        if self.is_page() {
79            self.generic_args.first()
80        } else {
81            None
82        }
83    }
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
87pub enum TypeArity {
88    Required,
89    Optional,
90    List,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
94pub struct Attribute {
95    pub raw: String,
96    pub span: SourceSpan,
97}