rainbow_core/vm/
parser.rs

1use std::{collections::BTreeMap, str::FromStr};
2
3use rainbow_pest::{
4    ast::{ASTProgram, ASTStatement, MetaStatement, RangedObject, RangedValue, SchemaStatement},
5    Error, ParserConfig, Rule,
6};
7
8use crate::{schema::Value, RainbowError, Result, Schema};
9
10impl From<Error<Rule>> for RainbowError {
11    fn from(e: Error<Rule>) -> Self {
12        todo!("{}", e)
13    }
14}
15
16impl FromStr for Schema {
17    type Err = RainbowError;
18
19    fn from_str(s: &str) -> Result<Self> {
20        let parser = ParserConfig::default();
21        let ast = parser.parse(s)?;
22        Schema::try_from(ast)
23    }
24}
25
26impl TryFrom<ASTProgram> for Schema {
27    type Error = RainbowError;
28
29    fn try_from(program: ASTProgram) -> Result<Self> {
30        let mut out = Schema::default();
31        let mut ctx = SchemaContext::default();
32        for i in program.statements {
33            match i {
34                ASTStatement::Import(node) => {
35                    println!("{:#?}", node);
36                    todo!()
37                }
38                ASTStatement::Schema(node) => {
39                    out.eval_schema(node, &mut ctx)?;
40                }
41                ASTStatement::Meta(node) => {
42                    out.eval_meta(node, &mut ctx)?;
43                }
44                ASTStatement::Language(node) => {
45                    println!("{:#?}", node);
46                    todo!()
47                }
48            }
49        }
50        Ok(out)
51    }
52}
53
54impl Default for SchemaContext {
55    fn default() -> Self {
56        Self { first_schema: true }
57    }
58}
59
60struct SchemaContext {
61    first_schema: bool,
62}
63
64impl Schema {
65    fn eval_schema(&mut self, ast: SchemaStatement, ctx: &mut SchemaContext) -> Result<()> {
66        if ctx.first_schema {
67            ctx.first_schema = false
68        }
69        else {
70            return Err(RainbowError::duplicate_declaration("schema"));
71        }
72        self.schema = ast.schema;
73        if let Some(v) = ast.object.get_string("theme") {
74            self.theme = v
75        }
76        if let Some(v) = ast.object.get_string("variant") {
77            self.variant = v
78        }
79        Ok(())
80    }
81    fn eval_meta(&mut self, ast: MetaStatement, ctx: &mut SchemaContext) -> Result<()> {
82        self.custom.insert(ast.meta, Value::eval_object(ast.object, ctx)?);
83        Ok(())
84    }
85}
86
87impl Value {
88    fn eval_object(o: RangedObject, ctx: &mut SchemaContext) -> Result<Self> {
89        let mut out = BTreeMap::new();
90        for (k, ranged) in o.inner {
91            let v = match ranged {
92                RangedValue::Null => Value::null(),
93                RangedValue::String(v) => Value::string(v),
94                RangedValue::Number(v) => Value::number(v),
95                RangedValue::Boolean(v) => Value::boolean(v),
96                RangedValue::Color(v) => Value::color(v),
97                RangedValue::Array(v) => {
98                    todo!()
99                }
100                RangedValue::Namespace(v) => Value::reference(v),
101                RangedValue::Object(v) => todo!(),
102            };
103            out.insert(k, v);
104        }
105        return todo!();
106    }
107}