byteorm_lib/
parser.rs

1// src/parser.rs
2use pest::iterators::Pair;
3use crate::ast::*;
4use crate::{Rule, SchemaParser};
5use pest::Parser;
6
7pub fn parse_schema(src: &str) -> Result<Schema, String> {
8    SchemaParser::parse(Rule::schema, src)
9        .map_err(|e| format!("Parse error: {}", e))
10        .and_then(|mut pairs| {
11            let schema_pair = pairs.next().ok_or("Empty schema")?;
12            Ok(build_ast(schema_pair))
13        })
14}
15
16pub(crate) fn build_ast(pair: Pair<Rule>) -> Schema {
17    let mut models = Vec::new();
18    for inner in pair.into_inner() {
19        match inner.as_rule() {
20            Rule::model_decl => models.push(parse_model(inner)),
21            _ => (),
22        }
23    }
24    Schema { models }
25}
26
27fn parse_model(pair: Pair<Rule>) -> Model {
28    let mut pairs = pair.into_inner();
29    let name = pairs.next().unwrap().as_str().to_string();
30    let mut fields = Vec::new();
31    for pair in pairs {
32        if matches!(pair.as_rule(), Rule::field_decl) {
33            fields.push(parse_field(pair));
34        }
35    }
36    Model { name, fields }
37}
38
39fn parse_field(pair: Pair<Rule>) -> Field {
40    let mut pairs = pair.into_inner();
41    let name = pairs.next().unwrap().as_str().to_string();
42    let type_name = pairs.next().unwrap().as_str().to_string();
43
44    let mut modifiers = Vec::new();
45    let mut attributes = Vec::new();
46
47    for pair in pairs {
48        match pair.as_rule() {
49            Rule::modifier => {
50                if let Ok(m) = parse_modifier(pair) {
51                    modifiers.push(m);
52                }
53            }
54            Rule::attr => attributes.push(parse_attribute(pair)),
55            _ => (),
56        }
57    }
58
59    Field { name, type_name, modifiers, attributes }
60}
61
62fn parse_modifier(pair: Pair<Rule>) -> Result<Modifier, String> {
63    let mut inner = pair.into_inner();
64    let mod_name = inner.next().unwrap().as_str();
65    let args = inner.next().map(|p| {
66        p.into_inner()
67            .next()
68            .map(|ac| ac.as_str().trim().to_string())
69            .unwrap_or_default()
70    });
71
72    match mod_name {
73        "PrimaryKey" => Ok(Modifier::PrimaryKey),
74        "NotNull" => Ok(Modifier::NotNull),
75        "Nullable" => Ok(Modifier::Nullable),
76        "Unique" => Ok(Modifier::Unique),
77        "ForeignKey" => parse_foreign_key(args),
78        _ => Err(format!("Unknown modifier: {}", mod_name)),
79    }
80}
81
82fn parse_foreign_key(args: Option<String>) -> Result<Modifier, String> {
83    let arg_str = args.ok_or("ForeignKey requires arguments")?;
84
85    // Parse "Model.field" or "Model(field)"
86    if let Some(dot_pos) = arg_str.find('.') {
87        let model = arg_str[..dot_pos].trim().to_string();
88        let field = arg_str[dot_pos + 1..].trim().to_string();
89        return Ok(Modifier::ForeignKey {
90            model,
91            field: Some(field),
92        });
93    }
94
95    if let Some(paren_pos) = arg_str.find('(') {
96        let model = arg_str[..paren_pos].trim().to_string();
97        if let Some(close_pos) = arg_str.find(')') {
98            let field = arg_str[paren_pos + 1..close_pos].trim().to_string();
99            return Ok(Modifier::ForeignKey {
100                model,
101                field: Some(field),
102            });
103        }
104    }
105
106    Ok(Modifier::ForeignKey {
107        model: arg_str,
108        field: None,
109    })
110}
111
112fn parse_attribute(pair: Pair<Rule>) -> Attribute {
113    let mut inner = pair.into_inner();
114    let name = inner.next().unwrap().as_str().to_string();
115    let args = inner.next().map(|p| {
116        p.as_str().to_string()
117    });
118    Attribute { name, args }
119}
120