From f6afba993fff4de8b040d1a2b579f691b37dbb01 Mon Sep 17 00:00:00 2001 From: "Arthur G.P. Schuster" Date: Fri, 8 Aug 2025 07:38:48 +0200 Subject: [PATCH] convert back to JS values --- Cargo.lock | 3 +- Cargo.toml | 1 + index.html | 48 +++++++++++++------------- src/lib.rs | 98 ++++++++++++++++++++++++++++-------------------------- 4 files changed, 78 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c751387..6b6bd6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,12 +115,13 @@ dependencies = [ [[package]] name = "cel-rust-wasm" -version = "0.1.0" +version = "0.2.0" dependencies = [ "cel", "chrono", "console_error_panic_hook", "js-sys", + "serde", "serde-wasm-bindgen", "wasm-bindgen", "web-sys", diff --git a/Cargo.toml b/Cargo.toml index f94d5f9..3537c58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["cdylib"] wasm-bindgen = "0.2" js-sys = "0.3" cel = "0.11" +serde = { version = "1.0", features = ["derive"] } serde-wasm-bindgen = "0.6" chrono = { version = "0.4", features = ["serde"] } diff --git a/index.html b/index.html index b9ebb25..3485bef 100644 --- a/index.html +++ b/index.html @@ -137,8 +137,8 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
- - + +
@@ -208,7 +208,7 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive diff --git a/src/lib.rs b/src/lib.rs index ec41415..cd92cf4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use cel::{Context, Program, Value}; use js_sys; +use serde::Serialize; use std::collections::HashMap; use wasm_bindgen::prelude::*; @@ -19,31 +20,6 @@ macro_rules! console_log { ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) } -#[wasm_bindgen] -pub struct CelResult { - success: bool, - result: String, - error: Option, -} - -#[wasm_bindgen] -impl CelResult { - #[wasm_bindgen(getter)] - pub fn success(&self) -> bool { - self.success - } - - #[wasm_bindgen(getter)] - pub fn result(&self) -> String { - self.result.clone() - } - - #[wasm_bindgen(getter)] - pub fn error(&self) -> Option { - self.error.clone() - } -} - /// Convert a JavaScript value to a CEL Value recursively fn js_value_to_cel_value(js_val: &JsValue) -> Result { if js_val.is_null() || js_val.is_undefined() { @@ -94,41 +70,67 @@ fn js_value_to_cel_value(js_val: &JsValue) -> Result { } } -/// Evaluate a CEL expression with the given context -#[wasm_bindgen] -pub fn evaluate_cel(expression: &str, context: &JsValue) -> CelResult { - let result = evaluate_cel_internal(expression, context); +// Simple wrapper to make Value serializable for JS conversion +#[derive(Serialize)] +#[serde(untagged)] +enum SerializableValue { + Null, + Bool(bool), + Int(i64), + Float(f64), + String(String), + List(Vec), + Map(HashMap), + Other(String), +} - match result { - Ok(value) => CelResult { - success: true, - result: format!("{:?}", value), - error: None, - }, - Err(error) => CelResult { - success: false, - result: String::new(), - error: Some(error), - }, +fn cel_value_to_serializable(cel_val: &Value) -> SerializableValue { + match cel_val { + Value::Null => SerializableValue::Null, + Value::Bool(b) => SerializableValue::Bool(*b), + Value::Int(i) => SerializableValue::Int(*i), + Value::UInt(u) => SerializableValue::Int(*u as i64), + Value::Float(f) => SerializableValue::Float(*f), + Value::String(s) => SerializableValue::String(s.to_string()), + Value::List(_list) => { + // For now, convert to string representation + // We can improve this later when we figure out the exact CEL API + SerializableValue::Other(format!("{:?}", cel_val)) + } + Value::Map(_map) => { + // For now, convert to string representation + // We can improve this later when we figure out the exact CEL API + SerializableValue::Other(format!("{:?}", cel_val)) + } + _ => SerializableValue::Other(format!("{:?}", cel_val)), } } -/// Evaluate a CEL expression and return the result as a string +/// Evaluate a CEL expression and return the actual JavaScript value #[wasm_bindgen] -pub fn evaluate_cel_string(expression: &str, context: &JsValue) -> Result { +pub fn evaluate_cel(expression: &str, context: &JsValue) -> Result { match evaluate_cel_internal(expression, context) { Ok(cel_value) => { - // Convert the result to a reasonable string representation - let result_string = match &cel_value { - Value::String(s) => s.clone(), - _ => format!("{:?}", cel_value).into(), - }; - Ok(result_string.to_string()) + // Convert to serializable format and then to JS + let serializable = cel_value_to_serializable(&cel_value); + match serde_wasm_bindgen::to_value(&serializable) { + Ok(js_val) => Ok(js_val), + Err(e) => Err(JsValue::from_str(&format!("Serialization error: {}", e))), + } } Err(e) => Err(JsValue::from_str(&e)), } } +/// Evaluate a CEL expression and return the result as a debug string +#[wasm_bindgen] +pub fn evaluate_cel_debug(expression: &str, context: &JsValue) -> Result { + match evaluate_cel_internal(expression, context) { + Ok(cel_value) => Ok(format!("{:?}", cel_value)), + Err(e) => Err(JsValue::from_str(&e)), + } +} + fn evaluate_cel_internal(expression: &str, context: &JsValue) -> Result { // Compile the CEL expression let program = Program::compile(expression).map_err(|e| format!("Compilation error: {}", e))?;