@@ -6,8 +6,16 @@ use anathema_store::slab::{Slab, SlabIndex};
66use crate :: error:: ErrorKind ;
77use crate :: expressions:: Expression ;
88
9+ #[ derive( Debug , Clone ) ]
10+ enum Global {
11+ // The global value was set from the runtime
12+ Runtime ( Expression ) ,
13+ // The global value originates from a template
14+ Template ( Expression ) ,
15+ }
16+
917#[ derive( Debug , Default , Clone ) ]
10- pub struct Globals ( HashMap < String , Expression > ) ;
18+ pub struct Globals ( HashMap < String , Global > ) ;
1119
1220impl Globals {
1321 pub fn empty ( ) -> Self {
@@ -19,15 +27,31 @@ impl Globals {
1927 }
2028
2129 pub fn get ( & self , ident : & str ) -> Option < & Expression > {
22- self . 0 . get ( ident)
30+ match self . 0 . get ( ident) ? {
31+ Global :: Runtime ( expression) | Global :: Template ( expression) => Some ( expression) ,
32+ }
2333 }
2434
25- pub fn set ( & mut self , ident : String , value : Expression ) {
35+ fn set ( & mut self , ident : String , value : Global ) {
2636 if self . 0 . contains_key ( & ident) {
2737 return ;
2838 }
2939 _ = self . 0 . insert ( ident, value) ;
3040 }
41+
42+ fn clear_template_globals ( & mut self ) {
43+ let mut clear = vec ! [ ] ;
44+ for ( key, glob) in & self . 0 {
45+ match glob {
46+ Global :: Runtime ( _) => continue ,
47+ Global :: Template ( _) => clear. push ( key. to_owned ( ) ) ,
48+ }
49+ }
50+
51+ for key in clear {
52+ _ = self . 0 . remove ( & key) ;
53+ }
54+ }
3155}
3256
3357#[ derive( Debug , Copy , Clone , PartialEq ) ]
@@ -252,16 +276,34 @@ impl Variables {
252276 var_id
253277 }
254278
255- pub fn define_global ( & mut self , ident : impl Into < String > , value : impl Into < Expression > ) -> Result < ( ) , ErrorKind > {
279+ fn set_global ( & mut self , ident : impl Into < String > , global : Global ) -> Result < ( ) , ErrorKind > {
256280 let ident = ident. into ( ) ;
257281 if self . globals . contains ( & ident) {
258282 return Err ( ErrorKind :: GlobalAlreadyAssigned ( ident) ) ;
259283 }
260284
261- self . globals . set ( ident, value . into ( ) ) ;
285+ self . globals . set ( ident, global ) ;
262286 Ok ( ( ) )
263287 }
264288
289+ /// Reset the globals defined in the template.
290+ /// This keeps any globals registered through Rust
291+ pub fn reset_globals ( & mut self ) {
292+ self . globals . clear_template_globals ( ) ;
293+ }
294+
295+ pub fn register_global ( & mut self , ident : impl Into < String > , value : impl Into < Expression > ) -> Result < ( ) , ErrorKind > {
296+ let expression = value. into ( ) ;
297+ let global = Global :: Runtime ( expression) ;
298+ self . set_global ( ident, global)
299+ }
300+
301+ pub fn define_global ( & mut self , ident : impl Into < String > , value : impl Into < Expression > ) -> Result < ( ) , ErrorKind > {
302+ let expression = value. into ( ) ;
303+ let global = Global :: Template ( expression) ;
304+ self . set_global ( ident, global)
305+ }
306+
265307 pub fn define_local ( & mut self , ident : impl Into < String > , value : impl Into < Expression > ) -> VarId {
266308 let value = value. into ( ) ;
267309 let scope_id = self . current . clone ( ) ;
0 commit comments