capnweb_core/protocol/
evaluator.rs1use super::expression::Expression;
5use super::ids::{ExportId, ImportId};
6use super::remap_engine::{RemapEngine, RemapError};
7use super::tables::{ExportTable, ImportTable, Value};
8use std::future::Future;
9use std::pin::Pin;
10use std::sync::Arc;
11
12pub struct ExpressionEvaluator {
14 #[allow(dead_code)]
15 imports: Arc<ImportTable>,
16 #[allow(dead_code)]
17 exports: Arc<ExportTable>,
18 remap_engine: RemapEngine,
19}
20
21impl ExpressionEvaluator {
22 pub fn new(imports: Arc<ImportTable>, exports: Arc<ExportTable>) -> Self {
24 let remap_engine = RemapEngine::new(imports.clone(), exports.clone());
25 Self {
26 imports,
27 exports,
28 remap_engine,
29 }
30 }
31
32 pub fn evaluate(
34 &self,
35 expr: Expression,
36 ) -> Pin<Box<dyn Future<Output = Result<Value, EvaluatorError>> + Send + '_>> {
37 Box::pin(async move {
38 match expr {
39 Expression::Null => Ok(Value::Null),
40 Expression::Bool(b) => Ok(Value::Bool(b)),
41 Expression::Number(n) => Ok(Value::Number(n)),
42 Expression::String(s) => Ok(Value::String(s)),
43
44 Expression::Array(elements) => {
45 let mut values = Vec::new();
46 for elem in elements {
47 values.push(self.evaluate(elem).await?);
48 }
49 Ok(Value::Array(values))
50 }
51
52 Expression::Object(map) => {
53 let mut result = std::collections::HashMap::new();
54 for (key, val) in map {
55 result.insert(key, Box::new(self.evaluate(*val).await?));
56 }
57 Ok(Value::Object(result))
58 }
59
60 Expression::Date(millis) => Ok(Value::Date(millis)),
61
62 Expression::Error(err) => Ok(Value::Error {
63 error_type: err.error_type,
64 message: err.message,
65 stack: err.stack,
66 }),
67
68 Expression::EscapedArray(elements) => {
69 let mut values = Vec::new();
71 for elem in elements {
72 values.push(self.evaluate(elem).await?);
73 }
74 Ok(Value::Array(values))
75 }
76
77 Expression::Remap(remap) => {
78 self.remap_engine
80 .execute_remap(&remap, self)
81 .await
82 .map_err(EvaluatorError::RemapError)
83 }
84
85 Expression::Import(_) => Err(EvaluatorError::NotImplemented),
87 Expression::Pipeline(_) => Err(EvaluatorError::NotImplemented),
88 Expression::Export(_) => Err(EvaluatorError::NotImplemented),
89 Expression::Promise(_) => Err(EvaluatorError::NotImplemented),
90 }
91 })
92 }
93}
94
95#[derive(Debug, thiserror::Error)]
96pub enum EvaluatorError {
97 #[error("Expression evaluation not yet implemented")]
98 NotImplemented,
99
100 #[error("Unknown import: {0}")]
101 UnknownImport(ImportId),
102
103 #[error("Unknown export: {0}")]
104 UnknownExport(ExportId),
105
106 #[error("Invalid operation")]
107 InvalidOperation,
108
109 #[error("Remap execution error: {0}")]
110 RemapError(#[from] RemapError),
111}