@@ -21,10 +21,10 @@ use serde_json::{from_str, json, to_string, Value};
2121use serde_norway:: { from_reader, from_str as from_yaml_str} ;
2222
2323use crate :: pdl:: ast:: {
24- ArrayBlock , CallBlock , Closure , DataBlock , EmptyBlock , FunctionBlock , IfBlock , ImportBlock ,
25- IncludeBlock , ListOrString , MessageBlock , ModelBlock , ObjectBlock , PdlBlock , PdlParser ,
26- PdlResult , PdlUsage , PythonCodeBlock , ReadBlock , RepeatBlock , Role , Scope , SequencingBlock ,
27- StringOrBoolean , StringOrNull ,
24+ ArrayBlock , CallBlock , Closure , DataBlock , EmptyBlock , EvalsTo , Expr , FunctionBlock , IfBlock ,
25+ ImportBlock , IncludeBlock , ListOrString , MessageBlock , ModelBlock , ObjectBlock , PdlBlock ,
26+ PdlParser , PdlResult , PdlUsage , PythonCodeBlock , ReadBlock , RepeatBlock , Role , Scope ,
27+ SequencingBlock , StringOrBoolean , StringOrNull ,
2828} ;
2929
3030type Messages = Vec < ChatMessage > ;
@@ -207,6 +207,33 @@ impl<'a> Interpreter<'a> {
207207 } ) )
208208 }
209209
210+ /// Evaluate an Expr to a bool
211+ fn eval_to_bool (
212+ & self ,
213+ expr : & EvalsTo < StringOrBoolean , bool > ,
214+ state : & State ,
215+ ) -> Result < bool , PdlError > {
216+ match expr {
217+ EvalsTo :: Const ( b)
218+ | EvalsTo :: Expr ( Expr {
219+ pdl_expr : StringOrBoolean :: Boolean ( b) ,
220+ ..
221+ } ) => Ok ( b. clone ( ) ) ,
222+
223+ EvalsTo :: Jinja ( s)
224+ | EvalsTo :: Expr ( Expr {
225+ pdl_expr : StringOrBoolean :: String ( s) ,
226+ ..
227+ } ) => match self . eval ( s, state) ? {
228+ PdlResult :: Bool ( b) => Ok ( b. clone ( ) ) ,
229+ x => Err ( Box :: from ( format ! (
230+ "Expression {s} evaluated to non-boolean {:?}" ,
231+ x
232+ ) ) ) ,
233+ } ,
234+ }
235+ }
236+
210237 /// Evaluate String as a Jinja2 expression, expecting a string in response
211238 fn eval_to_string ( & self , expr : & String , state : & State ) -> Result < String , PdlError > {
212239 match self . eval ( expr, state) ? {
@@ -432,21 +459,13 @@ impl<'a> Interpreter<'a> {
432459 self . process_defs ( & meta. defs , state) . await ?;
433460 }
434461
435- let cond = match & block. condition {
436- StringOrBoolean :: Boolean ( b) => PdlResult :: Bool ( * b) ,
437- StringOrBoolean :: String ( s) => self . eval ( s, state) ?,
438- } ;
439-
440- match cond {
441- PdlResult :: Bool ( true ) => self . run_quiet ( & block. then , state) . await ,
442- PdlResult :: Bool ( false ) => match & block. else_ {
462+ if self . eval_to_bool ( & block. condition , state) ? {
463+ self . run_quiet ( & block. then , state) . await
464+ } else {
465+ match & block. else_ {
443466 Some ( else_block) => self . run_quiet ( & else_block, state) . await ,
444467 None => Ok ( ( "" . into ( ) , vec ! [ ] , PdlBlock :: If ( block. clone ( ) ) ) ) ,
445- } ,
446- x => Err ( Box :: from ( format ! (
447- "if block condition evaluated to non-boolean value: {:?}" ,
448- x
449- ) ) ) ,
468+ }
450469 }
451470 }
452471
0 commit comments