Skip to main content

ferriorm_core/
ast.rs

1//! Raw Abstract Syntax Tree types produced by the parser.
2//!
3//! These types represent the `.ferriorm` schema file exactly as written, before any
4//! validation or resolution takes place. They preserve source location spans for
5//! error reporting and map one-to-one with the grammar rules in `grammar.pest`.
6//!
7//! After parsing, the AST is fed into the validator
8//! ([`crate::schema`] / `ferriorm_parser::validator`) which resolves types,
9//! infers table names, and produces the canonical [`crate::schema::Schema`] IR.
10
11/// A source location span.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct Span {
14    pub start: usize,
15    pub end: usize,
16}
17
18/// The top-level schema file.
19#[derive(Debug, Clone)]
20pub struct SchemaFile {
21    pub datasource: Option<Datasource>,
22    pub generators: Vec<Generator>,
23    pub enums: Vec<EnumDef>,
24    pub models: Vec<ModelDef>,
25}
26
27/// `datasource db { ... }`
28#[derive(Debug, Clone)]
29pub struct Datasource {
30    pub name: String,
31    pub provider: String,
32    pub url: StringOrEnv,
33    pub span: Span,
34}
35
36/// A string value that may reference an environment variable.
37#[derive(Debug, Clone)]
38pub enum StringOrEnv {
39    Literal(String),
40    Env(String),
41}
42
43/// `generator client { ... }`
44#[derive(Debug, Clone)]
45pub struct Generator {
46    pub name: String,
47    pub output: Option<String>,
48    pub span: Span,
49}
50
51/// `enum Role { User Admin Moderator }`
52#[derive(Debug, Clone)]
53pub struct EnumDef {
54    pub name: String,
55    pub variants: Vec<String>,
56    pub db_name: Option<String>,
57    pub span: Span,
58}
59
60/// `model User { ... }`
61#[derive(Debug, Clone)]
62pub struct ModelDef {
63    pub name: String,
64    pub fields: Vec<FieldDef>,
65    pub attributes: Vec<BlockAttribute>,
66    pub span: Span,
67}
68
69/// A single field in a model.
70#[derive(Debug, Clone)]
71pub struct FieldDef {
72    pub name: String,
73    pub field_type: FieldType,
74    pub attributes: Vec<FieldAttribute>,
75    pub span: Span,
76}
77
78/// The type of a field (e.g., `String`, `Int?`, `Post[]`).
79#[derive(Debug, Clone)]
80pub struct FieldType {
81    pub name: String,
82    pub is_list: bool,
83    pub is_optional: bool,
84}
85
86/// Attributes on a field (e.g., `@id`, `@default(uuid())`).
87#[derive(Debug, Clone)]
88pub enum FieldAttribute {
89    Id,
90    Unique,
91    Default(DefaultValue),
92    UpdatedAt,
93    Relation(RelationAttribute),
94    Map(String),
95    DbType(String, Vec<String>),
96}
97
98/// Default value for a field.
99#[derive(Debug, Clone)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub enum DefaultValue {
102    Uuid,
103    Cuid,
104    AutoIncrement,
105    Now,
106    Literal(LiteralValue),
107    EnumVariant(String),
108}
109
110/// A literal value in the schema.
111#[derive(Debug, Clone)]
112#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
113pub enum LiteralValue {
114    String(String),
115    Int(i64),
116    Float(f64),
117    Bool(bool),
118}
119
120/// `@relation(fields: [...], references: [...])`
121#[derive(Debug, Clone)]
122pub struct RelationAttribute {
123    pub name: Option<String>,
124    pub fields: Vec<String>,
125    pub references: Vec<String>,
126    pub on_delete: Option<ReferentialAction>,
127    pub on_update: Option<ReferentialAction>,
128}
129
130/// Referential actions for foreign keys.
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
133pub enum ReferentialAction {
134    Cascade,
135    Restrict,
136    NoAction,
137    SetNull,
138    SetDefault,
139}
140
141/// Block-level attributes (e.g., `@@index`, `@@unique`, `@@map`, `@@id`).
142#[derive(Debug, Clone)]
143pub enum BlockAttribute {
144    Index(Vec<String>),
145    Unique(Vec<String>),
146    Map(String),
147    Id(Vec<String>),
148}