cog_task/resource/function/
mod.rs1use 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}