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 get_audit_model(&self) -> Option<String> {
46        for attr in &self.attributes {
47            if attr.name == "audit" {
48                return attr.args.as_ref().map(|args| {
49
50                    let trimmed = if args.starts_with('(') && args.ends_with(')') {
51                        &args[1..args.len()-1]
52                    } else {
53                        args
54                    };
55                    trimmed.trim().to_string()
56                });
57            }
58        }
59        None
60    }
61
62    pub fn is_sql_default(&self) -> bool {
63        if let Some(value) = self.get_default_value() {
64            !value.contains("./") && !value.contains("../")
65        } else {
66            false
67        }
68    }
69
70
71    pub fn get_default_from_file(&self) -> Result<String, Box<dyn std::error::Error>> {
72        if let Some(value) = self.get_default_value() {
73            if value.starts_with("./") || value.starts_with("../") {
74                let content = std::fs::read_to_string(&value)?;
75                return Ok(content);
76            }
77            Ok(value)
78        } else {
79            Err("No default specified".into())
80        }
81    }
82}
83
84
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub enum Modifier {
88    PrimaryKey,
89    NotNull,
90    Nullable,
91    Unique,
92    ForeignKey { model: String, field: Option<String> },
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct Attribute {
97    pub name: String,
98    pub args: Option<String>,
99}