cog_task/resource/function/
mod.rs

1use eyre::{eyre, Error, Result};
2use serde::{Deserialize, Serialize};
3use serde_cbor::Value;
4use std::collections::BTreeMap;
5
6mod fasteval;
7#[cfg(feature = "python")]
8mod python;
9#[cfg(feature = "savage")]
10mod savage;
11
12pub type VarMap = BTreeMap<String, Value>;
13pub type LoopbackResult = Box<dyn FnOnce(Value) + Send>;
14pub type LoopbackError = Box<dyn FnOnce(Error) + Send>;
15
16#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
17#[serde(rename_all = "snake_case")]
18pub enum Interpreter {
19    Inherit,
20    Fasteval,
21    #[cfg(feature = "savage")]
22    Savage,
23    #[cfg(feature = "python")]
24    Python,
25}
26
27pub enum Evaluator {
28    Fasteval(fasteval::Evaluator),
29    #[cfg(feature = "savage")]
30    Savage(savage::Evaluator),
31    #[cfg(feature = "python")]
32    Python(python::Evaluator),
33}
34
35impl Default for Interpreter {
36    fn default() -> Self {
37        Interpreter::Inherit
38    }
39}
40
41impl Interpreter {
42    pub fn parse(&self, init: &str, expr: &str, vars: &mut VarMap) -> Result<Evaluator> {
43        match self {
44            Interpreter::Inherit => Err(eyre!("Cannot parse with interpreter=`Inherit`.")),
45            Interpreter::Fasteval => Ok(Evaluator::Fasteval(fasteval::Evaluator::new(
46                init, expr, vars,
47            )?)),
48            #[cfg(feature = "savage")]
49            Interpreter::Savage => Ok(Evaluator::Savage(savage::Evaluator::new(init, expr, vars)?)),
50            #[cfg(feature = "python")]
51            Interpreter::Python => Ok(Evaluator::Python(python::Evaluator::new(init, expr, vars)?)),
52        }
53    }
54
55    pub fn or(&self, other: &Self) -> Self {
56        if let Self::Inherit = self {
57            *other
58        } else {
59            *self
60        }
61    }
62}
63
64impl Evaluator {
65    pub fn eval(&self, vars: &mut VarMap) -> Result<Value> {
66        match self {
67            Evaluator::Fasteval(evaler) => evaler.eval(vars),
68            #[cfg(feature = "savage")]
69            Evaluator::Savage(evaler) => evaler.eval(vars),
70            #[cfg(feature = "python")]
71            Evaluator::Python(evaler) => evaler.eval(vars),
72        }
73    }
74
75    pub fn eval_lazy(
76        &self,
77        vars: &mut VarMap,
78        loopback: LoopbackResult,
79        error: LoopbackError,
80    ) -> Result<()> {
81        match self {
82            Evaluator::Fasteval(evaler) => evaler.eval_lazy(vars, loopback, error),
83            #[cfg(feature = "savage")]
84            Evaluator::Savage(evaler) => evaler.eval_lazy(vars, loopback, error),
85            #[cfg(feature = "python")]
86            Evaluator::Python(evaler) => evaler.eval_lazy(vars, loopback, error),
87        }
88    }
89}