Skip to content

Commit 82ae542

Browse files
committed
feat: introduce Expr typing and apply it to IfBlock.condition
Signed-off-by: Nick Mitchell <[email protected]>
1 parent c9c8fc5 commit 82ae542

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

pdl-live-react/src-tauri/src/pdl/ast.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,23 @@ pub enum StringOrBoolean {
519519
Boolean(bool),
520520
}
521521

522+
#[derive(Serialize, Deserialize, Debug, Clone)]
523+
pub struct Expr<S, T> {
524+
#[serde(rename = "pdl__expr")]
525+
pub pdl_expr: S,
526+
527+
#[serde(rename = "pdl__result", skip_serializing_if = "Option::is_none")]
528+
pub pdl_result: Option<T>,
529+
}
530+
531+
#[derive(Serialize, Deserialize, Debug, Clone)]
532+
#[serde(untagged)]
533+
pub enum EvalsTo<S, T> {
534+
Const(T),
535+
Jinja(String),
536+
Expr(Expr<S, T>),
537+
}
538+
522539
/// Conditional control structure.
523540
///
524541
/// Example:
@@ -535,7 +552,7 @@ pub enum StringOrBoolean {
535552
pub struct IfBlock {
536553
/// The condition to check
537554
#[serde(rename = "if")]
538-
pub condition: StringOrBoolean,
555+
pub condition: EvalsTo<StringOrBoolean, bool>,
539556

540557
/// Branch to execute if the condition is true
541558
pub then: Box<PdlBlock>,

pdl-live-react/src-tauri/src/pdl/interpreter.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ use serde_json::{from_str, json, to_string, Value};
2121
use serde_norway::{from_reader, from_str as from_yaml_str};
2222

2323
use 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

3030
type 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

Comments
 (0)