capnweb_core/protocol/
evaluator.rs

1// Expression evaluator for Cap'n Web protocol
2// This module evaluates expressions to produce values
3
4use 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
12/// Expression evaluator context
13pub 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    /// Create a new expression evaluator
23    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    /// Evaluate an expression to produce a value
33    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                    // Escaped arrays are just regular arrays in evaluation
70                    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                    // Execute remap using the remap engine
79                    self.remap_engine
80                        .execute_remap(&remap, self)
81                        .await
82                        .map_err(EvaluatorError::RemapError)
83                }
84
85                // TODO: Implement import, pipeline, export, promise evaluation
86                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}