1- use std:: {
2- fmt:: Display ,
3- fs,
4- path:: { Path , PathBuf } ,
5- sync:: Mutex ,
6- } ;
1+ use std:: fmt:: Display ;
2+ use std:: fs;
3+ use std:: path:: { Path , PathBuf } ;
74
85use erased_serde:: Serialize ;
9- use lol_html:: { HtmlRewriter , Settings , element, html_content:: Element } ;
10- use mlua:: { Lua , LuaSerdeExt } ;
6+ use lawl:: Lawl ;
117
128pub struct TemplateEngine {
139 base_path : PathBuf ,
1410 layout_path : PathBuf ,
1511 use_layout : bool ,
16- environment : Vec < ( String , Mutex < Box < dyn Serialize + Send > > ) > ,
12+ lawl : Lawl ,
1713}
1814
1915impl TemplateEngine {
@@ -26,128 +22,38 @@ impl TemplateEngine {
2622 pub fn render ( & mut self , template_name : impl AsRef < Path > ) -> anyhow:: Result < String > {
2723 let path = self . get_path_to_template ( & template_name) ;
2824 let mut template = fs:: read_to_string ( path) ?;
29- let mut rendered = template . render ( & self . environment ) ? ;
25+ let mut rendered = self . lawl . render ( & template ) . unwrap ( ) ;
3026
3127 if self . use_layout {
32- self . set ( "children" , rendered) ;
28+ self . lawl . insert ( & "children" , rendered) ;
3329 template = fs:: read_to_string ( self . get_path_to_template ( & self . layout_path ) ) ?;
34- rendered = template . render ( & self . environment ) ? ;
35- self . delete ( "children" ) ;
30+ rendered = self . lawl . render ( & template ) . unwrap ( ) ;
31+ self . lawl . remove ( & "children" ) ;
3632 }
3733
3834 Ok ( rendered)
3935 }
4036
41- pub fn set < K : Display , T : Serialize + Send + ' static > ( & mut self , key : K , value : T ) {
42- self . environment
43- . push ( ( key. to_string ( ) , Mutex :: new ( Box :: new ( value) ) ) ) ;
37+ pub fn insert < T : Sync + Send + Serialize + ' static > (
38+ & mut self ,
39+ key : & impl Display ,
40+ value : T ,
41+ ) -> Result < ( ) , ( ) > {
42+ self . lawl . insert ( & key. to_string ( ) , value)
4443 }
4544
46- pub fn delete < K : Display > ( & mut self , key : K ) {
47- let key = key. to_string ( ) ;
48-
49- self . environment . retain ( |( k, _) | & key != k) ;
45+ pub fn remove ( & mut self , key : & impl Display ) -> Result < ( ) , ( ) > {
46+ self . lawl . remove ( & key)
5047 }
5148}
5249
5350impl Default for TemplateEngine {
5451 fn default ( ) -> Self {
5552 Self {
5653 base_path : Path :: new ( & "./views" . to_string ( ) ) . to_owned ( ) ,
57- environment : Vec :: new ( ) ,
5854 use_layout : true ,
5955 layout_path : Path :: new ( & "layout" . to_string ( ) ) . to_owned ( ) ,
56+ lawl : Default :: default ( ) ,
6057 }
6158 }
6259}
63-
64- pub trait Render {
65- fn render (
66- & self ,
67- environment : & Vec < ( String , Mutex < Box < dyn Serialize + Send > > ) > ,
68- ) -> anyhow:: Result < String > ;
69- }
70-
71- impl Render for String {
72- fn render (
73- & self ,
74- environment : & Vec < ( String , Mutex < Box < dyn Serialize + Send > > ) > ,
75- ) -> anyhow:: Result < String > {
76- let mut env = vec ! [ ] ;
77- let lua = Lua :: new ( ) ;
78-
79- for ( k, v) in environment {
80- let value = v. lock ( ) . unwrap ( ) ;
81- let value = value. as_ref ( ) ;
82-
83- let value = lua. to_value ( & value) . unwrap ( ) ;
84- env. push ( ( k. to_owned ( ) , value) ) ;
85- }
86-
87- for ( k, v) in env {
88- lua. globals ( ) . set ( k, v) . expect ( "Unable to assign globals." )
89- }
90-
91- lua. load ( "function show(v) if (v or '') == '' then data = '' end end" )
92- . exec ( )
93- . unwrap ( ) ;
94-
95- lua. load ( "function hide(v) if (v or '') ~= '' then data = '' end end" )
96- . exec ( )
97- . unwrap ( ) ;
98-
99- lua. load ( "function maybe(v, o) return v or o end" )
100- . exec ( )
101- . unwrap ( ) ;
102-
103- lua. load ( "function format(...) data = string.format(data, ...) end" )
104- . exec ( )
105- . unwrap ( ) ;
106-
107- lua. load ( "function each(k) local template = data; data = ''; for _, post in ipairs(k) do data = data .. template:gsub('%$([a-zA-Z_]+)', post) end end" ) . exec ( ) . unwrap ( ) ;
108-
109- render ( self , lua)
110- }
111- }
112-
113- pub fn render ( template : & String , lua : Lua ) -> anyhow:: Result < String > {
114- let mut buffer = vec ! [ ] ;
115- let mut rewriter = HtmlRewriter :: new (
116- Settings {
117- element_content_handlers : vec ! [ element!( "lua" , |el: & mut Element | {
118- let start_location = el. source_location( ) . bytes( ) . end;
119- let expression = el. get_attribute( "code" ) . unwrap_or( "" . to_string( ) ) ;
120- el. remove( ) ;
121- if let Some ( handlers) = el. end_tag_handlers( ) {
122- let source = template. clone( ) ;
123- let e = expression. clone( ) ;
124- let lua = lua. clone( ) ;
125-
126- handlers. push( Box :: new( move |end| {
127- let end_location = end. source_location( ) . bytes( ) . start;
128- let html = source[ start_location..end_location] . to_string( ) ;
129-
130- lua. globals( ) . set( "data" , html) . unwrap( ) ;
131-
132- lua. load( & e)
133- . exec( )
134- . expect( format!( "Invalid Lua expression. {}" , e) . as_str( ) ) ;
135-
136- let data: String = lua. globals( ) . get( "data" ) . unwrap( ) ;
137-
138- end. before( & data, lol_html:: html_content:: ContentType :: Html ) ;
139-
140- Ok ( ( ) )
141- } ) ) ;
142- }
143- Ok ( ( ) )
144- } ) ] ,
145- ..Settings :: new ( )
146- } ,
147- |c : & [ u8 ] | buffer. extend_from_slice ( c) ,
148- ) ;
149-
150- rewriter. write ( template. as_bytes ( ) ) . unwrap ( ) ;
151-
152- Ok ( String :: from_utf8 ( buffer) . unwrap ( ) )
153- }
0 commit comments