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    /// `name 名詞`。テーブルの名詞。省略するとブロックの識別子を使う。
93    Name(Spanned<Value>),
94    Column(Column),
95    Pk(Vec<Name>),
96    Index(Index),
97    Use(Name),
98    Override(Override),
99    Except(Vec<Name>),
100    ExceptIndex(Vec<Name>),
101    Relation(Relation),
102}
103
104#[derive(Debug, Clone)]
105pub struct Table {
106    pub name: Name,
107    pub members: Vec<Spanned<Member>>,
108    pub span: Span,
109}
110
111#[derive(Debug, Clone)]
112pub struct Mixin {
113    pub name: Name,
114    pub members: Vec<Spanned<Member>>,
115    pub span: Span,
116}
117
118#[derive(Debug, Clone)]
119pub struct Blueprint {
120    pub name: Name,
121    pub params: Vec<Name>,
122    pub tables: Vec<Table>,
123    pub span: Span,
124}
125
126#[derive(Debug, Clone)]
127pub struct MacroCall {
128    pub name: Name,
129    pub args: Vec<Name>,
130    /// 生成するテーブルの名詞。`associate` のみ。
131    pub table_name: Option<Spanned<Value>>,
132    /// 生成するテーブルのコメント。`associate` のみ。
133    pub comment: Option<Spanned<String>>,
134    pub span: Span,
135}
136
137#[derive(Debug, Clone)]
138pub struct Assign {
139    pub key: Name,
140    pub value: Spanned<Value>,
141}
142
143#[derive(Debug, Clone)]
144pub struct ConfigBlock {
145    pub name: Name,
146    pub entries: Vec<Assign>,
147    pub span: Span,
148}
149
150#[derive(Debug, Clone)]
151pub struct Noun {
152    /// ソースが名詞を指す名前。`table` や `belongs_to` が書くのはこれ。
153    /// 出力には出ない。省略された語形の種になるだけ。
154    pub id: Name,
155    /// 省略時は識別子。
156    pub singular: Option<Name>,
157    /// 省略時は単数形の規則変化。
158    pub plural: Option<Name>,
159    /// 名前を詰めたいときの形。省略時は単数形。
160    pub short: Option<Name>,
161    pub comment: Option<Spanned<String>>,
162}
163
164#[derive(Debug, Clone)]
165pub struct NounsBlock {
166    pub entries: Vec<Noun>,
167    pub span: Span,
168}
169
170#[derive(Debug, Clone, Default)]
171pub struct Document {
172    pub naming: Option<ConfigBlock>,
173    pub constraints: Option<ConfigBlock>,
174    pub nouns: Option<NounsBlock>,
175    pub mixins: Vec<Mixin>,
176    pub blueprints: Vec<Blueprint>,
177    pub tables: Vec<Table>,
178    pub macros: Vec<MacroCall>,
179}