rainbow_core/vm/
parser.rs1use 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}