Skip to main content

nounsql_core/
ast.rs

1use crate::span::{Span, Spanned};
2
3pub type Name = Spanned<String>;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum Value {
7    Ident(String),
8    Str(String),
9    Num(String),
10    /// `eval(...)` の中身。DB側で評価される式。
11    Eval(String),
12    List(Vec<Name>),
13    Call {
14        name: Name,
15        args: Vec<Spanned<Value>>,
16    },
17}
18
19#[derive(Debug, Clone)]
20pub struct Attr {
21    pub key: Name,
22    pub value: Spanned<Value>,
23}
24
25#[derive(Debug, Clone)]
26pub struct Column {
27    pub name: Name,
28    pub attrs: Vec<Attr>,
29}
30
31#[derive(Debug, Clone)]
32pub struct Index {
33    pub columns: Vec<Name>,
34    pub unique: bool,
35}
36
37#[derive(Debug, Clone)]
38pub struct Override {
39    pub name: Name,
40    pub attrs: Vec<Attr>,
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum RelationKind {
45    BelongsTo,
46    UniqueBelongsTo,
47    HasMany,
48    HasOne,
49}
50
51impl RelationKind {
52    pub fn keyword(self) -> &'static str {
53        match self {
54            RelationKind::BelongsTo => "belongs_to",
55            RelationKind::UniqueBelongsTo => "unique_belongs_to",
56            RelationKind::HasMany => "has_many",
57            RelationKind::HasOne => "has_one",
58        }
59    }
60
61    /// FK列を生成する側か。
62    pub fn owns_fk(self) -> bool {
63        matches!(
64            self,
65            RelationKind::BelongsTo | RelationKind::UniqueBelongsTo
66        )
67    }
68
69    pub fn is_unique(self) -> bool {
70        matches!(self, RelationKind::UniqueBelongsTo | RelationKind::HasOne)
71    }
72}
73
74#[derive(Debug, Clone)]
75pub struct Relation {
76    pub kind: RelationKind,
77    pub target: Name,
78    /// FK列名。`belongs_to` 系のみ。
79    pub fk: Option<Spanned<String>>,
80    /// この側の関連名。文字列か `noun(...)`。
81    pub alias: Option<Spanned<Value>>,
82    /// 対応するFK列名。`has_many` 系のみ。
83    pub via: Option<Spanned<String>>,
84    /// FK列のコメント。`belongs_to` 系のみ。
85    pub comment: Option<Spanned<String>>,
86}
87
88#[derive(Debug, Clone)]
89pub enum Member {
90    /// `comment "..."`。テーブルの説明。
91    Comment(Spanned<String>),
92    Column(Column),
93    Pk(Vec<Name>),
94    Index(Index),
95    Use(Name),
96    Override(Override),
97    Except(Vec<Name>),
98    ExceptIndex(Vec<Name>),
99    Relation(Relation),
100}
101
102#[derive(Debug, Clone)]
103pub struct Table {
104    pub name: Name,
105    pub members: Vec<Spanned<Member>>,
106    pub span: Span,
107}
108
109#[derive(Debug, Clone)]
110pub struct Mixin {
111    pub name: Name,
112    pub members: Vec<Spanned<Member>>,
113    pub span: Span,
114}
115
116#[derive(Debug, Clone)]
117pub struct Let {
118    pub name: Name,
119    pub value: Spanned<Value>,
120}
121
122#[derive(Debug, Clone)]
123pub enum BlueprintItem {
124    Let(Let),
125    Table(Table),
126}
127
128#[derive(Debug, Clone)]
129pub struct Blueprint {
130    pub name: Name,
131    pub params: Vec<Name>,
132    pub items: Vec<BlueprintItem>,
133    pub span: Span,
134}
135
136#[derive(Debug, Clone)]
137pub struct MacroCall {
138    pub name: Name,
139    pub args: Vec<Name>,
140    /// 生成するテーブルの名詞。`associate` のみ。
141    pub table_name: Option<Spanned<Value>>,
142    /// 生成するテーブルのコメント。`associate` のみ。
143    pub comment: Option<Spanned<String>>,
144    pub span: Span,
145}
146
147#[derive(Debug, Clone)]
148pub struct Assign {
149    pub key: Name,
150    pub value: Spanned<Value>,
151}
152
153#[derive(Debug, Clone)]
154pub struct ConfigBlock {
155    pub name: Name,
156    pub entries: Vec<Assign>,
157    pub span: Span,
158}
159
160#[derive(Debug, Clone)]
161pub struct Noun {
162    pub singular: Name,
163    pub plural: Name,
164    pub comment: Option<Spanned<String>>,
165}
166
167#[derive(Debug, Clone)]
168pub struct NounsBlock {
169    pub entries: Vec<Noun>,
170    pub span: Span,
171}
172
173#[derive(Debug, Clone, Default)]
174pub struct Document {
175    pub naming: Option<ConfigBlock>,
176    pub constraints: Option<ConfigBlock>,
177    pub nouns: Option<NounsBlock>,
178    pub mixins: Vec<Mixin>,
179    pub blueprints: Vec<Blueprint>,
180    pub tables: Vec<Table>,
181    pub macros: Vec<MacroCall>,
182}