Skip to main content

camel_language_js/
engine.rs

1//! [`JsEngine`] trait — abstraction over the JS runtime.
2
3use std::collections::HashMap;
4
5use serde_json::Value;
6
7use crate::error::JsLanguageError;
8
9/// A snapshot of exchange state passed into and out of JS evaluation.
10#[derive(Debug, Clone, Default)]
11pub struct JsExchange {
12    pub headers: HashMap<String, Value>,
13    pub body: Value,
14    pub properties: HashMap<String, Value>,
15}
16
17impl JsExchange {
18    pub fn from_headers_body_properties(
19        headers: HashMap<String, Value>,
20        body: Value,
21        properties: HashMap<String, Value>,
22    ) -> Self {
23        Self {
24            headers,
25            body,
26            properties,
27        }
28    }
29}
30
31/// The result of evaluating a JS expression.
32#[derive(Debug, Clone)]
33pub struct JsEvalResult {
34    /// The return value of the expression (last evaluated value).
35    pub return_value: Value,
36    /// Possibly-modified headers after execution.
37    pub headers: HashMap<String, Value>,
38    /// Possibly-modified body after execution.
39    pub body: Value,
40    /// Possibly-modified properties after execution.
41    pub properties: HashMap<String, Value>,
42}
43
44/// Abstraction over a JavaScript engine capable of evaluating expressions
45/// against a [`JsExchange`] context.
46pub trait JsEngine: Send + Sync + 'static {
47    /// Evaluate `source` JavaScript code with the given exchange context.
48    ///
49    /// Returns the result including the (potentially mutated) exchange state.
50    fn eval(&self, source: &str, exchange: JsExchange) -> Result<JsEvalResult, JsLanguageError>;
51
52    /// Validate that `source` is syntactically valid JavaScript without executing it.
53    fn validate(&self, source: &str) -> Result<(), JsLanguageError>;
54}