@@ -16,7 +16,7 @@ pub fn template(
1616 env : Option < & str > ,
1717 prompts : & HashMap < String , String > ,
1818 secrets : & HashMap < String , String > ,
19- provider_values : & HashMap < String , String > ,
19+ provider_values : & HashMap < String , String > , // TODO: Wire this up
2020) -> Result < TemplatedRequestFile , Vec < Spanned < ReqlangError > > > {
2121 let ast = Ast :: from ( reqfile_string) ;
2222 let parsed_reqfile = parse ( & ast) ?;
@@ -90,66 +90,70 @@ pub fn template(
9090 // Gather list of template references along with each reference's type
9191 //
9292 // e.g. ("{{:var_name}}", ReferenceType::Variable("var_name"))
93- let template_refs_to_replace: Vec < ( String , ReferenceType ) > = reqfile
93+ let template_refs_to_replace: Vec < ( String , ReferenceType , Span ) > = reqfile
9494 . refs
9595 . iter ( )
96- . map ( |( template_reference, _) | {
97- ( format ! ( "{template_reference}" ) , template_reference. clone ( ) )
96+ . map ( |( template_reference, template_reference_span) | {
97+ (
98+ format ! ( "{template_reference}" ) ,
99+ template_reference. clone ( ) ,
100+ template_reference_span. clone ( ) ,
101+ )
98102 } )
99103 . collect ( ) ;
100104
101105 // If the environment is provided, use it to resolve template references
106+ let default_variable_values = parsed_reqfile. default_variable_values ( ) ;
102107 let vars = match env {
103- Some ( env) => reqfile. env ( env) . unwrap_or_default ( ) ,
108+ Some ( env) => reqfile. env ( env) . unwrap_or ( default_variable_values ) ,
104109 None => HashMap :: new ( ) ,
105110 } ;
106111
107- let default_variable_values = parsed_reqfile. default_variable_values ( ) ;
108- let default_prompt_values = parsed_reqfile. default_prompt_values ( ) ;
109-
110- // Replace template references with the resolved values
111- for ( template_ref, ref_type) in & template_refs_to_replace {
112- let value = match ref_type {
113- ReferenceType :: Variable ( name) => {
114- vars. get ( name) . or ( default_variable_values. get ( name) )
115- }
116- ReferenceType :: Prompt ( name) => {
117- prompts. get ( name) . or ( default_prompt_values. get ( name) )
118- }
119- ReferenceType :: Secret ( name) => secrets. get ( name) ,
120- ReferenceType :: Provider ( name) => provider_values. get ( name) ,
121- _ => None ,
122- } ;
123-
124- // If reference can not be resolved, keep the template reference as is
125- if value. is_some ( ) {
126- input = input. replace ( template_ref, value. unwrap ( ) ) ;
127- }
128- }
129-
130- let mut compiler_env =
131- CompileTimeEnv :: new ( reqfile. vars ( ) , reqfile. prompts ( ) , reqfile. secrets ( ) , vec ! [ ] ) ;
112+ let mut compiler_env = CompileTimeEnv :: new (
113+ reqfile. vars ( ) ,
114+ reqfile. prompts ( ) ,
115+ reqfile. secrets ( ) ,
116+ provider_values. keys ( ) . map ( |x| x. clone ( ) ) . collect ( ) ,
117+ ) ;
132118
133119 let mut runtime_env = {
134- let var_values = match env {
120+ let var_values: Vec < String > = match env {
135121 Some ( env) => reqfile
136122 . vars ( )
137123 . iter ( )
138124 . map ( |x| {
139125 let config = parsed_reqfile. config . clone ( ) . unwrap ( ) . 0 . env ( env) . unwrap ( ) ;
140- let value = config. get ( x) . unwrap ( ) ;
126+ let value = config
127+ . get ( & x. clone ( ) . clone ( ) )
128+ . unwrap_or ( & vars. get ( & x. clone ( ) . clone ( ) ) . unwrap ( ) ) ;
141129
142130 value. clone ( )
143131 } )
144132 . collect ( ) ,
145- None => vec ! [ ] ,
133+ None => provider_values . values ( ) . map ( |x| x . clone ( ) ) . collect ( ) ,
146134 } ;
147135
148- let prompt_values: Vec < Option < String > > = reqfile
149- . prompts ( )
150- . iter ( )
151- . map ( |x| prompts. get ( x) . cloned ( ) )
152- . collect ( ) ;
136+ let prompt_values = {
137+ let default_prompt_values = parsed_reqfile. default_prompt_values ( ) ;
138+
139+ let prompt_values = reqfile
140+ . prompts ( )
141+ . iter ( )
142+ . map ( |x| {
143+ let value = prompts. get ( x) . cloned ( ) . unwrap_or (
144+ default_prompt_values
145+ . get ( x)
146+ . cloned ( )
147+ . unwrap_or_default ( )
148+ . clone ( ) ,
149+ ) ;
150+
151+ value. clone ( )
152+ } )
153+ . collect ( ) ;
154+
155+ prompt_values
156+ } ;
153157
154158 let secret_values: Vec < Option < String > > = reqfile
155159 . secrets ( )
@@ -159,7 +163,7 @@ pub fn template(
159163
160164 RuntimeEnv {
161165 vars : var_values. clone ( ) ,
162- prompts : prompt_values. iter ( ) . filter_map ( |x| x . clone ( ) ) . collect ( ) ,
166+ prompts : prompt_values,
163167 secrets : secret_values. iter ( ) . filter_map ( |x| x. clone ( ) ) . collect ( ) ,
164168 client_context : vec ! [ ] ,
165169 }
@@ -173,6 +177,60 @@ pub fn template(
173177
174178 let mut vm = Vm :: new ( ) ;
175179
180+ for ( _, ref_type, ref_span) in & template_refs_to_replace {
181+ match reqlang_expr:: parser:: parse ( & ref_type. lookup_name ( ) ) {
182+ Ok ( expr) => match compile ( & mut ( expr, ref_span. clone ( ) ) , & compiler_env) {
183+ Ok ( bytecode) => {
184+ let result = vm. interpret ( bytecode. into ( ) , & compiler_env, & runtime_env) ;
185+
186+ let replacement_string = match result {
187+ Ok ( expr_value) => expr_value
188+ . get_string ( )
189+ . expect ( "should be string" )
190+ . to_string ( ) ,
191+ Err ( expr_errs) => {
192+ templating_errors. push ( (
193+ ReqlangError :: ResolverError (
194+ ResolverError :: ExpressionEvaluationError (
195+ ref_type. lookup_name ( ) . clone ( ) ,
196+ format ! ( "{expr_errs:#?}" ) ,
197+ ) ,
198+ ) ,
199+ ref_span. clone ( ) ,
200+ ) ) ;
201+
202+ // In the case of an error, replacement string
203+ // is the original string
204+ ref_type. lookup_name ( ) . clone ( )
205+ }
206+ } ;
207+
208+ let x = format ! ( "{{{{{}}}}}" , ref_type. lookup_name( ) ) ;
209+
210+ input = input. replace ( & x, & replacement_string) ;
211+ }
212+ Err ( expr_errs) => {
213+ templating_errors. push ( (
214+ ReqlangError :: ResolverError ( ResolverError :: ExpressionEvaluationError (
215+ ref_type. lookup_name ( ) . clone ( ) ,
216+ format ! ( "{expr_errs:#?}" ) ,
217+ ) ) ,
218+ ref_span. clone ( ) ,
219+ ) ) ;
220+ }
221+ } ,
222+ Err ( expr_errs) => {
223+ templating_errors. push ( (
224+ ReqlangError :: ResolverError ( ResolverError :: ExpressionEvaluationError (
225+ ref_type. lookup_name ( ) . clone ( ) ,
226+ format ! ( "{expr_errs:#?}" ) ,
227+ ) ) ,
228+ ref_span. clone ( ) ,
229+ ) ) ;
230+ }
231+ }
232+ }
233+
176234 let items = & reqfile. exprs . to_vec ( ) ;
177235 for ( expr_ref, expr_span) in items {
178236 match reqlang_expr:: parser:: parse ( & format ! ( "({expr_ref})" ) ) {
0 commit comments