byteorm_lib/
ast.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct Schema {
5    pub models: Vec<Model>,
6}
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Model {
10    pub name: String,
11    pub fields: Vec<Field>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct Field {
16    pub name: String,
17    pub type_name: String,
18    pub modifiers: Vec<Modifier>,
19    pub attributes: Vec<Attribute>,
20}
21
22impl Field {
23    pub fn get_default_value(&self) -> Option<String> {
24        for attr in &self.attributes {
25            if attr.name == "default" {
26                return attr.args.as_ref().map(|args| {
27                    let trimmed = if args.starts_with('(') && args.ends_with(')') {
28                        &args[1..args.len()-1]
29                    } else {
30                        args
31                    };
32
33                    if (trimmed.starts_with('\'') && trimmed.ends_with('\'')) ||
34                        (trimmed.starts_with('"') && trimmed.ends_with('"')) {
35                        trimmed[1..trimmed.len()-1].to_string()
36                    } else {
37                        trimmed.to_string()
38                    }
39                });
40            }
41        }
42        None
43    }
44
45    pub fn is_jsonb_default_file(&self) -> bool {
46        self.get_default_value()
47            .map(|v| v.ends_with(".json"))
48            .unwrap_or(false)
49    }
50
51    pub fn get_jsonb_default_path(&self) -> Option<String> {
52        if self.type_name == "JsonB" && self.is_jsonb_default_file() {
53            self.get_default_value()
54        } else {
55            None
56        }
57    }
58
59    pub fn get_audit_model(&self) -> Option<String> {
60        for attr in &self.attributes {
61            if attr.name == "audit" {
62                return attr.args.as_ref().map(|args| {
63
64                    let trimmed = if args.starts_with('(') && args.ends_with(')') {
65                        &args[1..args.len()-1]
66                    } else {
67                        args
68                    };
69                    trimmed.trim().to_string()
70                });
71            }
72        }
73        None
74    }
75
76    pub fn is_sql_default(&self) -> bool {
77        self.get_default_value().is_some() && !self.is_jsonb_default_file()
78    }
79
80
81    pub fn get_default_from_file(&self) -> Result<String, Box<dyn std::error::Error>> {
82        if let Some(value) = self.get_default_value() {
83            if value.starts_with("./") || value.starts_with("../") {
84                let content = std::fs::read_to_string(&value)?;
85                return Ok(content);
86            }
87            Ok(value)
88        } else {
89            Err("No default specified".into())
90        }
91    }
92}
93
94
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub enum Modifier {
98    PrimaryKey,
99    NotNull,
100    Nullable,
101    Unique,
102    ForeignKey { model: String, field: Option<String> },
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct Attribute {
107    pub name: String,
108    pub args: Option<String>,
109}