use crate::core::{RustValue, Value};
use crate::eval::{ControlFlow, ErrorKind, EvalResult, Evaluator};
#[derive(Debug, Clone)]
pub struct EvalTry {
pub body: Value,
pub catch_pattern: super::eval_ref::EvalPattern,
pub catch_body: Value,
}
#[crate::rust_value_any]
impl RustValue for EvalTry {
fn dyn_clone(&self) -> Box<dyn RustValue> {
Box::new(self.clone())
}
fn eval(&self, evaluator: &mut Evaluator) -> anyhow::Result<EvalResult> {
match self.body.eval(evaluator)? {
Ok(value) => Ok(Ok(value)),
Err(ControlFlow::Error(ErrorKind::RaisedError(error_value))) => {
match evaluator.match_pattern(&self.catch_pattern, &error_value) {
Ok(_) => {
self.catch_body.eval(evaluator)
}
Err(e) => Ok(Err(e)),
}
}
Err(other_control_flow) => {
Ok(Err(other_control_flow))
}
}
}
fn str(&self) -> String {
format!(
"try {} catch {:?} {}",
self.body.str(),
self.catch_pattern,
self.catch_body.str()
)
}
}