summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/context.rs91
-rw-r--r--src/lexer.rs2
-rw-r--r--src/lib.rs53
-rw-r--r--src/parser.rs23
4 files changed, 104 insertions, 65 deletions
diff --git a/src/context.rs b/src/context.rs
index 4de5b45..4501a0a 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -1,6 +1,8 @@
1use std::collections::HashMap; 1use std::collections::HashMap;
2use std::fmt; 2use std::fmt;
3 3
4use crate::error::CrimResult;
5
4use crate::{Identifier,IdentifierValue}; 6use crate::{Identifier,IdentifierValue};
5 7
6pub type Context = HashMap<String,Value>; 8pub type Context = HashMap<String,Value>;
@@ -10,42 +12,32 @@ pub trait MappedStructure<'a> {
10} 12}
11 13
12impl<'a> MappedStructure<'a> for Context { 14impl<'a> MappedStructure<'a> for Context {
13 fn get_value(&'a self, _id: &str) -> Option<MappedValue<'a>> { 15 fn get_value(&'a self, id: &str) -> Option<MappedValue<'a>> {
14 /* 16 self.get(id).map(|v|Into::<MappedValue<'a>>::into(v))
15 if id.len() == 0 {
16 return None;
17 }
18 let mut cur_val : Option<&MappedValue> = if let IdentifierValue::Name(s) = &id[0] {
19 self.get(s)
20 } else {
21 return None;
22 };
23 if cur_val.is_none() {
24 return None;
25 }
26
27 for idx in 1..id.len() {
28 if let IdentifierValue::Name(s) = &id[idx] &&
29 let Some(MappedValue::Dictionary(d)) = &cur_val {
30 cur_val.replace( if let Some(v) = d.get(s) {
31 v
32 } else {
33 return None;
34 });
35 }
36 }
37
38 return cur_val.cloned();
39 */
40
41 None
42 } 17 }
43} 18}
44 19
45pub trait MappedList<'a> { 20pub trait MappedList<'a> {
46 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>>; 21 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>>;
47// fn get_iterator(&'a self) -> MappedListIterator<'a>; 22 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String>;
48 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>)); 23}
24
25impl<'a> MappedList<'a> for Vec<Value> {
26 fn get_index(&'a self, id: usize) -> Option<MappedValue<'a>> {
27 if let Some(x) = self.get(id) {
28 Some(x.into())
29 } else {
30 None
31 }
32 }
33
34 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String> {
35 let mut buf = String::new();
36 for i in self {
37 func( &Into::<MappedValue<'a>>::into( i ), &mut buf )?;
38 }
39 Ok(buf)
40 }
49} 41}
50 42
51pub enum MappedValue<'a> { 43pub enum MappedValue<'a> {
@@ -90,37 +82,42 @@ impl<'a> fmt::Debug for MappedValue<'a> {
90 82
91} 83}
92 84
93pub struct StatefulContext<'a, T: MappedStructure<'a>> { 85pub struct StatefulContext<'a> {
94 root: &'a T, 86 root: &'a dyn MappedStructure<'a>,
95 local: &'a T, 87 local: &'a dyn MappedStructure<'a>,
96} 88}
97 89
98impl<'a, T: MappedStructure<'a>> StatefulContext<'a, T> { 90impl<'a> StatefulContext<'a> {
99 pub fn root( root: &'a T ) -> Self { 91 pub fn root( root: &'a dyn MappedStructure<'a> ) -> Self {
100 Self { 92 Self {
101 root, local: root, 93 root, local: root,
102 } 94 }
103 } 95 }
104 96
105 pub fn local(&self, local: &'a T ) -> Self { 97 pub fn local(&self, local: &'a dyn MappedStructure<'a> ) -> Self {
106 Self { 98 Self {
107 root: self.root, 99 root: self.root,
108 local 100 local
109 } 101 }
110 } 102 }
111 103
112 pub fn full( root: &'a T, local: &'a T ) -> Self { 104 pub fn full( root: &'a dyn MappedStructure<'a>, local: &'a dyn MappedStructure<'a> ) -> Self {
113 Self { 105 Self {
114 root, local 106 root, local
115 } 107 }
116 } 108 }
117 109
118 pub fn get_value(&self, id: &[IdentifierValue]) -> Option<MappedValue<'a>> { 110 pub fn get_value(&self, id: &[IdentifierValue]) -> Option<MappedValue<'a>> {
119 let mut value : Option<MappedValue> = Some(MappedValue::Struct(self.root)); 111 let mut value : Option<MappedValue> =
112 if id[0] == IdentifierValue::Root {
113 Some(MappedValue::Struct(self.root))
114 } else {
115 Some(MappedValue::Struct(self.local))
116 };
120 for idpart in id { 117 for idpart in id {
121 match idpart { 118 match idpart {
122 IdentifierValue::Root => { 119 IdentifierValue::Root => {
123 return None 120 continue;
124 } 121 }
125 IdentifierValue::Name(name) => { 122 IdentifierValue::Name(name) => {
126 if let Some(MappedValue::Struct(s)) = value && 123 if let Some(MappedValue::Struct(s)) = value &&
@@ -139,6 +136,20 @@ impl<'a, T: MappedStructure<'a>> StatefulContext<'a, T> {
139 } 136 }
140} 137}
141 138
139impl<'a> From<&'a Value> for MappedValue<'a> {
140 fn from(value: &'a Value) -> Self {
141 match value {
142 Value::Dictionary(ctx) => MappedValue::Struct(ctx),
143 Value::List(list) => MappedValue::List(list),
144 Value::String(s) => MappedValue::String(s),
145 Value::Int(i) => MappedValue::Int64(*i),
146 Value::Float(f) => MappedValue::Float64(*f),
147 Value::Bool(b) => MappedValue::Bool(*b),
148 Value::Identifier(_identifier) => panic!("Identifier!?"),
149 }
150 }
151}
152
142#[derive(Debug,Clone)] 153#[derive(Debug,Clone)]
143pub enum Value { 154pub enum Value {
144 Dictionary(Context), 155 Dictionary(Context),
diff --git a/src/lexer.rs b/src/lexer.rs
index 4e95854..d4d39e9 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -66,9 +66,11 @@ impl<'a> Symbol<'a> {
66 &self.start 66 &self.start
67 } 67 }
68 68
69 /*
69 pub fn end(&self) -> &Position { 70 pub fn end(&self) -> &Position {
70 &self.end 71 &self.end
71 } 72 }
73 */
72} 74}
73 75
74#[derive(Debug)] 76#[derive(Debug)]
diff --git a/src/lib.rs b/src/lib.rs
index 95462b4..9867615 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -41,12 +41,12 @@ struct View {
41} 41}
42 42
43impl View { 43impl View {
44 fn process<T: for<'a> MappedStructure<'a>>(&self, input: &T) -> CrimResult<Context> { 44 fn process(&self, input: &dyn for<'a> MappedStructure<'a>) -> CrimResult<Context> {
45 let mut out_vars = Context::new(); 45 let mut out_vars = Context::new();
46 for output in &self.outputs { 46 for output in &self.outputs {
47 let mut buf = String::new(); 47 let mut buf = String::new();
48 let sc = StatefulContext::root( input ); 48 let sc = StatefulContext::root( input );
49 exec::<T>( &sc, &output.code, &mut buf )?; 49 exec( &sc, &output.code, &mut buf )?;
50 out_vars.insert( output.name.clone(), Value::String(buf) ); 50 out_vars.insert( output.name.clone(), Value::String(buf) );
51 } 51 }
52 Ok(out_vars) 52 Ok(out_vars)
@@ -163,7 +163,7 @@ impl Crimtag {
163 } 163 }
164 } 164 }
165 165
166 pub fn render_partial<T: for<'a> MappedStructure<'a>>(&self, view: &str, input: &T ) -> CrimResult<Context> { 166 pub fn render_partial(&self, view: &str, input: &dyn for<'a> MappedStructure<'a> ) -> CrimResult<Context> {
167 if let Some(view) = self.views.get(view) { 167 if let Some(view) = self.views.get(view) {
168 return view.process( input ) 168 return view.process( input )
169 } else { 169 } else {
@@ -171,7 +171,7 @@ impl Crimtag {
171 } 171 }
172 } 172 }
173 173
174 pub fn render<T: for<'a> MappedStructure<'a>>(&self, view: &str, input: &T ) -> CrimResult<String> { 174 pub fn render(&self, view: &str, input: &dyn for<'a> MappedStructure<'a> ) -> CrimResult<String> {
175 if let Some(view) = self.views.get( view ) { 175 if let Some(view) = self.views.get( view ) {
176 //println!("::Token tree::\n{:?}", view ); 176 //println!("::Token tree::\n{:?}", view );
177 let mut output = view.process( input )?; 177 let mut output = view.process( input )?;
@@ -193,19 +193,23 @@ impl Crimtag {
193 } 193 }
194} 194}
195 195
196fn exec<T: for<'a> MappedStructure<'a>>(input: &StatefulContext<T>, tokens: &Vec<Token>, buf: &mut String) -> CrimResult<()> { 196fn exec<'a>(input: &StatefulContext<'a>, tokens: &Vec<Token>, buf: &mut String) -> CrimResult<()> {
197 for token in tokens { 197 for token in tokens {
198 match token { 198 match token {
199 Token::Loop(ident,code) => { 199 Token::Loop(ident,code) => {
200 //println!("!!! Loop over: {:?} {:?}", ident, input.get_value( &ident ));
200 if let Some(value) = input.get_value( &ident ) && 201 if let Some(value) = input.get_value( &ident ) &&
201 let MappedValue::List(list) = value { 202 let MappedValue::List(list) = value {
202 list.for_each(&|rec: &MappedValue| { 203 let output =
203 if let MappedValue::Struct(d) = rec { 204 &list.for_each(&|rec: &MappedValue, buf: &mut String| {
204 exec( &StatefulContext::root(d), code, buf )? 205 if let MappedValue::Struct(d) = rec {
205 } 206 exec( &input.local(*d), code, buf )?;
206 }); 207 }
208 Ok(())
209 })?;
210 //println!("!!! Output from loop: {}", output );
211 buf.push_str( &output );
207 } 212 }
208 return Ok(());
209 } 213 }
210 Token::If(ident,code,other) => { 214 Token::If(ident,code,other) => {
211 if let Some(value) = input.get_value( &ident ) && 215 if let Some(value) = input.get_value( &ident ) &&
@@ -360,7 +364,7 @@ Now with explicit outputs:
360 let mut ct = Crimtag::new(); 364 let mut ct = Crimtag::new();
361 ct.load_static(r#"Looping code: 365 ct.load_static(r#"Looping code:
362[|view "index"|>We will enumerate people here:[|loop people|> 366[|view "index"|>We will enumerate people here:[|loop people|>
363 - [|show last_name|], [|show first_name|][|if show_title |>: [|show title|] <|else|> **title redacted** <|if|] [|loop tags|> [|show tag|]<|loop|] <|loop|] 367 - [|show last_name|], [|show first_name|][|if show_title |>: [|show title|] <|else|> **title redacted** <|if|] ::>[|loop tags|> [|show tag|]<|loop|] <:: <|loop|]
364<|view|] 368<|view|]
365"#)?; 369"#)?;
366 370
@@ -371,24 +375,40 @@ Now with explicit outputs:
371 ("last_name".into(), "Smith".into()), 375 ("last_name".into(), "Smith".into()),
372 ("show_title".into(), true.into()), 376 ("show_title".into(), true.into()),
373 ("title".into(), "CEO".into()), 377 ("title".into(), "CEO".into()),
378 ("tags".into(), vec![
379 Context::from([("tag".into(), "jerk".into()),]).into(),
380 Context::from([("tag".into(), "ugly".into()),]).into(),
381 ].into()),
374 ].into(), 382 ].into(),
375 [ 383 [
376 ("first_name".into(), "Chris".into()), 384 ("first_name".into(), "Chris".into()),
377 ("last_name".into(), "Perkens".into()), 385 ("last_name".into(), "Perkens".into()),
378 ("show_title".into(), false.into()), 386 ("show_title".into(), false.into()),
379 ("title".into(), "Baconeer".into()), 387 ("title".into(), "Baconeer".into()),
388 ("tags".into(), vec![
389 Context::from([("tag".into(), "jerk".into()),]).into(),
390 Context::from([("tag".into(), "ugly".into()),]).into(),
391 ].into()),
380 ].into(), 392 ].into(),
381 [ 393 [
382 ("first_name".into(), "Will".into()), 394 ("first_name".into(), "Will".into()),
383 ("last_name".into(), "Power".into()), 395 ("last_name".into(), "Power".into()),
384 ("show_title".into(), false.into()), 396 ("show_title".into(), false.into()),
385 ("title".into(), "CFO".into()), 397 ("title".into(), "CFO".into()),
398 ("tags".into(), vec![
399 Context::from([("tag".into(), "jerk".into()),]).into(),
400 Context::from([("tag".into(), "ugly".into()),]).into(),
401 ].into()),
386 ].into(), 402 ].into(),
387 [ 403 [
388 ("first_name".into(), "Justin".into()), 404 ("first_name".into(), "Justin".into()),
389 ("last_name".into(), "Time".into()), 405 ("last_name".into(), "Time".into()),
390 ("show_title".into(), true.into()), 406 ("show_title".into(), true.into()),
391 ("title".into(), "CIO".into()), 407 ("title".into(), "CIO".into()),
408 ("tags".into(), vec![
409 Context::from([("tag".into(), "jerk".into()),]).into(),
410 Context::from([("tag".into(), "ugly".into()),]).into(),
411 ].into()),
392 ].into(), 412 ].into(),
393 ].into()), 413 ].into()),
394 ]); 414 ]);
@@ -513,10 +533,12 @@ Now with explicit outputs:
513 } 533 }
514 } 534 }
515 535
516 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>)) { 536 fn for_each(&'a self, func: &dyn Fn(&MappedValue<'a>, &mut String) -> CrimResult<()>) -> CrimResult<String> {
537 let mut buf = String::new();
517 for i in self { 538 for i in self {
518 func( &MappedValue::Struct(i) ); 539 func( &MappedValue::Struct(i), &mut buf )?;
519 } 540 }
541 Ok(buf)
520 } 542 }
521 } 543 }
522 544
@@ -529,10 +551,11 @@ Now with explicit outputs:
529 ); 551 );
530 552
531 if let Some(MappedValue::List(l)) = page.get_value(&"items") { 553 if let Some(MappedValue::List(l)) = page.get_value(&"items") {
532 l.for_each(&|x: &MappedValue| { 554 l.for_each(&|x: &MappedValue, buf: &mut String| {
533 if let MappedValue::Struct(s) = x { 555 if let MappedValue::Struct(s) = x {
534 println!(" - {:?}", s.get_value(&"title")); 556 println!(" - {:?}", s.get_value(&"title"));
535 } 557 }
558 Ok(())
536 }); 559 });
537 } 560 }
538 Ok(()) 561 Ok(())
diff --git a/src/parser.rs b/src/parser.rs
index d1fe4d7..4f7ff6a 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -35,6 +35,7 @@ impl<'a> Context<'a> {
35 self.cur[(self.icur+1)%2] 35 self.cur[(self.icur+1)%2]
36 } 36 }
37 37
38 /*
38 pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> CrimResult<bool> { 39 pub fn check_unwrapped<T: Fn( &SymbolType, &SymbolType ) -> bool>(&self, context: &str, f: T) -> CrimResult<bool> {
39 if self.cur().is_none() || self.peek().is_none() { 40 if self.cur().is_none() || self.peek().is_none() {
40 Err(CrimError::eos( context )) 41 Err(CrimError::eos( context ))
@@ -42,6 +43,7 @@ impl<'a> Context<'a> {
42 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) 43 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol()))
43 } 44 }
44 } 45 }
46 */
45 47
46 pub fn source(&self) -> usize { 48 pub fn source(&self) -> usize {
47 self.source 49 self.source
@@ -50,6 +52,7 @@ impl<'a> Context<'a> {
50 52
51trait SymbolHelper { 53trait SymbolHelper {
52 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool>; 54 fn is<T: Fn( &SymbolType ) -> bool>(&self, context: &str, f: T ) -> CrimResult<bool>;
55 #[allow(dead_code)]
53 fn is_valid_tag_name(&self) -> CrimResult<bool>; 56 fn is_valid_tag_name(&self) -> CrimResult<bool>;
54} 57}
55 58
@@ -572,11 +575,11 @@ impl<'a> TagBuilder<'a> {
572 pub fn is_unary(&self) -> bool { 575 pub fn is_unary(&self) -> bool {
573 self.tag_type == TagType::Unary 576 self.tag_type == TagType::Unary
574 } 577 }
575 578/*
576 pub fn is_multinary_open(&self) -> bool { 579 pub fn is_multinary_open(&self) -> bool {
577 self.tag_type == TagType::MultinaryOpen 580 self.tag_type == TagType::MultinaryOpen
578 } 581 }
579 582*/
580 pub fn can_have_params(&self) -> bool { 583 pub fn can_have_params(&self) -> bool {
581 match self.name.unwrap().symbol() { 584 match self.name.unwrap().symbol() {
582 SymbolType::View | SymbolType::Output | SymbolType::Loop => true, 585 SymbolType::View | SymbolType::Output | SymbolType::Loop => true,
@@ -598,7 +601,7 @@ impl<'a> TagBuilder<'a> {
598 pub fn can_have_props(&self) -> bool { 601 pub fn can_have_props(&self) -> bool {
599 true 602 true
600 } 603 }
601 604/*
602 pub fn can_have_children(&self) -> bool { 605 pub fn can_have_children(&self) -> bool {
603 if self.tag_type == TagType::MultinaryOpen || 606 if self.tag_type == TagType::MultinaryOpen ||
604 self.tag_type == TagType::MultinaryMid { 607 self.tag_type == TagType::MultinaryMid {
@@ -607,7 +610,7 @@ impl<'a> TagBuilder<'a> {
607 false 610 false
608 } 611 }
609 } 612 }
610 613*/
611 pub fn is_name(&self, name: &SymbolType<'a>) -> bool { 614 pub fn is_name(&self, name: &SymbolType<'a>) -> bool {
612 if let Some(a) = self.name { 615 if let Some(a) = self.name {
613 a.symbol() == name 616 a.symbol() == name
@@ -619,11 +622,11 @@ impl<'a> TagBuilder<'a> {
619 pub fn name(&self) -> Option<Symbol<'a>> { 622 pub fn name(&self) -> Option<Symbol<'a>> {
620 self.name 623 self.name
621 } 624 }
622 625/*
623 pub fn params(&self) -> &Vec<ParamValue> { 626 pub fn params(&self) -> &Vec<ParamValue> {
624 &self.params 627 &self.params
625 } 628 }
626 629*/
627 pub fn set_name(&mut self, name: Symbol<'a>) { 630 pub fn set_name(&mut self, name: Symbol<'a>) {
628 self.name = Some(name); 631 self.name = Some(name);
629 } 632 }
@@ -639,19 +642,19 @@ impl<'a> TagBuilder<'a> {
639 pub fn add_child(&mut self, tb: Entry<'a>) { 642 pub fn add_child(&mut self, tb: Entry<'a>) {
640 self.children.push( tb ); 643 self.children.push( tb );
641 } 644 }
642 645/*
643 pub fn append_children(&mut self, children: &mut Vec::<Entry<'a>>) { 646 pub fn append_children(&mut self, children: &mut Vec::<Entry<'a>>) {
644 self.children.append( children ); 647 self.children.append( children );
645 } 648 }
646 649*/
647 pub fn add_chain(&mut self, tb: Entry<'a>) { 650 pub fn add_chain(&mut self, tb: Entry<'a>) {
648 self.chain.push( tb ); 651 self.chain.push( tb );
649 } 652 }
650 653/*
651 pub fn set_type(&mut self, tag_type: TagType) { 654 pub fn set_type(&mut self, tag_type: TagType) {
652 self.tag_type = tag_type; 655 self.tag_type = tag_type;
653 } 656 }
654 657*/
655 pub fn tag_type(&self) -> TagType { 658 pub fn tag_type(&self) -> TagType {
656 self.tag_type 659 self.tag_type
657 } 660 }