twig/environment/
mod.rs

1use std::collections::HashMap;
2use std::collections::HashSet;
3
4use extension::{ Extension, CoreExtension };
5use operator::{ Operator, OperatorKind, OperatorOptions };
6use function::Function;
7use nodes::{ TokenParser, TokenParserExtension };
8
9/// Environment configuration.
10pub struct Config {
11    pub autoescape: String,
12}
13
14impl Config {
15    pub fn default() -> Config {
16        Config {
17            autoescape: "html".into()
18        }
19    }
20
21    pub fn from_hashmap(map: HashMap<String, String>) -> Config {
22        let default = Config::default();
23
24        Config {
25            autoescape: map.get("autoescape").cloned().unwrap_or(default.autoescape),
26        }
27    }
28}
29
30/// Project configuration container.
31#[derive(Debug)]
32pub struct Environment {
33    pub operators: Vec<Operator>,
34    pub token_parsers: Vec<TokenParser>,
35    pub functions: Vec<Function>,
36}
37
38impl Environment {
39
40    pub fn new(config: Config) -> Environment {
41        let mut staged = Environment {
42            operators: Vec::new(),
43            token_parsers: Vec::new(),
44            functions: Vec::new(),
45        };
46
47        CoreExtension::apply(&mut staged);
48
49        staged
50    }
51
52    pub fn default() -> Environment {
53        Environment::new(Config::default())
54    }
55
56    pub fn init_all(self) -> CompiledEnvironment {
57        CompiledEnvironment {
58            lexing: LexingEnvironment {
59                operators: {
60                    self.operators.iter()
61                        .filter_map(|i| match i.options.kind {
62                            OperatorKind::Unary { value, .. } => Some(value),
63                            OperatorKind::Binary { value, .. } => Some(value),
64                            OperatorKind::Other => None,
65                        })
66                        .collect()
67                },
68            },
69            parsing: ParsingEnvironment {
70                operators: {
71                    self.operators.into_iter()
72                        .filter_map(|i| match i.options.kind {
73                            OperatorKind::Unary { value, .. } => Some((value, i.options)),
74                            OperatorKind::Binary { value, .. } => Some((value, i.options)),
75                            OperatorKind::Other => None,
76                        })
77                        .collect()
78                },
79                handlers: {
80                    self.token_parsers.into_iter()
81                        .map(|i| (i.tag, i.extension))
82                        .collect()
83                },
84                functions: {
85                    self.functions.iter()
86                        .map(|f| f.name)
87                        .collect()
88                }
89            },
90        }
91    }
92
93    pub fn push_operators<I: IntoIterator<Item=Operator>>(&mut self, ops: I) {
94        self.operators.extend(ops);
95    }
96
97    pub fn push_token_parsers<I: IntoIterator<Item=TokenParser>>(&mut self, ops: I) {
98        self.token_parsers.extend(ops);
99    }
100
101    pub fn push_functions<I: IntoIterator<Item=Function>>(&mut self, funs: I) {
102        self.functions.extend(funs);
103    }
104}
105
106pub struct LexingEnvironment {
107    pub operators: HashSet<&'static str>,
108}
109
110pub struct ParsingEnvironment {
111    pub operators: HashMap<&'static str, OperatorOptions>,
112    pub handlers: HashMap<&'static str, Box<TokenParserExtension>>,
113    pub functions: HashSet<&'static str>,
114}
115
116/// Project configuration container with all extensions applied.
117pub struct CompiledEnvironment {
118    pub lexing: LexingEnvironment,
119    pub parsing: ParsingEnvironment,
120}
121
122impl CompiledEnvironment {
123
124    pub fn default() -> CompiledEnvironment {
125        Environment::default()
126            .init_all()
127    }
128}