fix compilation issues
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -115,11 +115,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cel-rust-wasm"
|
name = "cel-rust-wasm"
|
||||||
version = "0.2.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cel",
|
"cel",
|
||||||
"chrono",
|
"chrono",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
|
"js-sys",
|
||||||
"serde-wasm-bindgen",
|
"serde-wasm-bindgen",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ crate-type = ["cdylib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
|
js-sys = "0.3"
|
||||||
cel = "0.11"
|
cel = "0.11"
|
||||||
serde-wasm-bindgen = "0.6"
|
serde-wasm-bindgen = "0.6"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|||||||
15
README
15
README
@@ -16,3 +16,18 @@ To build and use this:
|
|||||||
# or
|
# or
|
||||||
npx serve .
|
npx serve .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4. Use the API:
|
||||||
|
```js
|
||||||
|
// Method 1: Get structured result
|
||||||
|
const result = evaluate_cel("name + ' is ' + string(age)", {name: "Alice", age: 30});
|
||||||
|
console.log(result.success, result.result, result.error);
|
||||||
|
|
||||||
|
// Method 2: Get string result or error
|
||||||
|
try {
|
||||||
|
const result = evaluate_cel_string("name + ' is ' + string(age)", {name: "Alice", age: 30});
|
||||||
|
console.log(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
21
index.html
21
index.html
@@ -138,7 +138,7 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
|
|
||||||
<div class="full-width">
|
<div class="full-width">
|
||||||
<button onclick="evaluate()">Evaluate CEL Expression</button>
|
<button onclick="evaluate()">Evaluate CEL Expression</button>
|
||||||
<button onclick="evaluateAsJs()">Evaluate & Return as JS Value</button>
|
<button onclick="evaluateAsString()">Evaluate & Return as String</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="full-width">
|
<div class="full-width">
|
||||||
@@ -208,7 +208,7 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
<script type="module">
|
<script type="module">
|
||||||
import init, {
|
import init, {
|
||||||
evaluate_cel,
|
evaluate_cel,
|
||||||
evaluate_cel_js,
|
evaluate_cel_string,
|
||||||
} from "./pkg/cel_rust_wasm.js";
|
} from "./pkg/cel_rust_wasm.js";
|
||||||
|
|
||||||
let wasmModule;
|
let wasmModule;
|
||||||
@@ -219,7 +219,7 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
|
|
||||||
// Make functions globally available
|
// Make functions globally available
|
||||||
window.evaluate_cel = evaluate_cel;
|
window.evaluate_cel = evaluate_cel;
|
||||||
window.evaluate_cel_js = evaluate_cel_js;
|
window.evaluate_cel_string = evaluate_cel_string;
|
||||||
|
|
||||||
// Enable the evaluate button
|
// Enable the evaluate button
|
||||||
document.querySelector("button").disabled = false;
|
document.querySelector("button").disabled = false;
|
||||||
@@ -230,7 +230,7 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
|
|
||||||
// Make functions globally available for onclick handlers
|
// Make functions globally available for onclick handlers
|
||||||
window.evaluate = evaluate;
|
window.evaluate = evaluate;
|
||||||
window.evaluateAsJs = evaluateAsJs;
|
window.evaluateAsString = evaluateAsString;
|
||||||
window.loadExample = loadExample;
|
window.loadExample = loadExample;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -266,8 +266,8 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateAsJs() {
|
function evaluateAsString() {
|
||||||
if (!window.evaluate_cel_js) {
|
if (!window.evaluate_cel_string) {
|
||||||
document.getElementById("result").textContent =
|
document.getElementById("result").textContent =
|
||||||
"WASM module not loaded yet...";
|
"WASM module not loaded yet...";
|
||||||
return;
|
return;
|
||||||
@@ -281,14 +281,11 @@ name + " is " + string(age) + " years old and " + (active ? "active" : "inactive
|
|||||||
// Parse the context as JavaScript object
|
// Parse the context as JavaScript object
|
||||||
const context = contextStr.trim() ? JSON.parse(contextStr) : {};
|
const context = contextStr.trim() ? JSON.parse(contextStr) : {};
|
||||||
|
|
||||||
// Evaluate using the JavaScript value result version
|
// Evaluate using the string result version
|
||||||
const result = window.evaluate_cel_js(expression, context);
|
const result = window.evaluate_cel_string(expression, context);
|
||||||
|
|
||||||
resultDiv.className = "result success";
|
resultDiv.className = "result success";
|
||||||
resultDiv.textContent = `Success (JS Value): ${JSON.stringify(result, null, 2)}`;
|
resultDiv.textContent = `Success (String): ${result}`;
|
||||||
|
|
||||||
// Log the actual JavaScript object to console
|
|
||||||
console.log("CEL Result as JavaScript value:", result);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
resultDiv.className = "result error";
|
resultDiv.className = "result error";
|
||||||
resultDiv.textContent = `Error: ${e}`;
|
resultDiv.textContent = `Error: ${e}`;
|
||||||
|
|||||||
77
src/lib.rs
77
src/lib.rs
@@ -1,5 +1,5 @@
|
|||||||
use cel::{Context, Program, Value};
|
use cel::{Context, Program, Value};
|
||||||
use serde_wasm_bindgen;
|
use js_sys;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@@ -48,12 +48,6 @@ impl CelResult {
|
|||||||
fn js_value_to_cel_value(js_val: &JsValue) -> Result<Value, String> {
|
fn js_value_to_cel_value(js_val: &JsValue) -> Result<Value, String> {
|
||||||
if js_val.is_null() || js_val.is_undefined() {
|
if js_val.is_null() || js_val.is_undefined() {
|
||||||
Ok(Value::Null)
|
Ok(Value::Null)
|
||||||
} else if js_val.is_bigint() {
|
|
||||||
// Handle BigInt
|
|
||||||
match js_val.as_f64() {
|
|
||||||
Some(n) => Ok(Value::Int(n as i64)),
|
|
||||||
None => Err("Failed to convert BigInt to number".to_string()),
|
|
||||||
}
|
|
||||||
} else if let Some(b) = js_val.as_bool() {
|
} else if let Some(b) = js_val.as_bool() {
|
||||||
Ok(Value::Bool(b))
|
Ok(Value::Bool(b))
|
||||||
} else if let Some(n) = js_val.as_f64() {
|
} else if let Some(n) = js_val.as_f64() {
|
||||||
@@ -96,58 +90,7 @@ fn js_value_to_cel_value(js_val: &JsValue) -> Result<Value, String> {
|
|||||||
|
|
||||||
Ok(Value::Map(cel_map.into()))
|
Ok(Value::Map(cel_map.into()))
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Unsupported JavaScript type: {:?}", js_val))
|
Err(format!("Unsupported JavaScript type"))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert a CEL Value back to a JavaScript value
|
|
||||||
fn cel_value_to_js_value(cel_val: &Value) -> Result<JsValue, String> {
|
|
||||||
match cel_val {
|
|
||||||
Value::Null => Ok(JsValue::NULL),
|
|
||||||
Value::Bool(b) => Ok(JsValue::from_bool(*b)),
|
|
||||||
Value::Int(i) => Ok(JsValue::from_f64(*i as f64)),
|
|
||||||
Value::UInt(u) => Ok(JsValue::from_f64(*u as f64)),
|
|
||||||
Value::Float(f) => Ok(JsValue::from_f64(*f)),
|
|
||||||
Value::String(s) => Ok(JsValue::from_str(s)),
|
|
||||||
Value::Bytes(b) => {
|
|
||||||
// Convert bytes to Uint8Array
|
|
||||||
let array = js_sys::Uint8Array::new_with_length(b.len() as u32);
|
|
||||||
for (i, byte) in b.iter().enumerate() {
|
|
||||||
array.set_index(i as u32, *byte);
|
|
||||||
}
|
|
||||||
Ok(array.into())
|
|
||||||
}
|
|
||||||
Value::List(list) => {
|
|
||||||
let array = js_sys::Array::new();
|
|
||||||
for item in list.iter() {
|
|
||||||
let js_item = cel_value_to_js_value(item)?;
|
|
||||||
array.push(&js_item);
|
|
||||||
}
|
|
||||||
Ok(array.into())
|
|
||||||
}
|
|
||||||
Value::Map(map) => {
|
|
||||||
let obj = js_sys::Object::new();
|
|
||||||
for (key, value) in map.iter() {
|
|
||||||
let js_value = cel_value_to_js_value(value)?;
|
|
||||||
js_sys::Reflect::set(&obj, &JsValue::from_str(key), &js_value)
|
|
||||||
.map_err(|_| "Failed to set object property".to_string())?;
|
|
||||||
}
|
|
||||||
Ok(obj.into())
|
|
||||||
}
|
|
||||||
Value::Duration(d) => {
|
|
||||||
// Convert duration to string representation
|
|
||||||
Ok(JsValue::from_str(&format!("{}s", d.as_secs_f64())))
|
|
||||||
}
|
|
||||||
Value::Timestamp(ts) => {
|
|
||||||
// Convert timestamp to ISO string
|
|
||||||
let datetime = chrono::DateTime::from_timestamp(ts.as_secs() as i64, ts.subsec_nanos())
|
|
||||||
.ok_or_else(|| "Invalid timestamp".to_string())?;
|
|
||||||
Ok(JsValue::from_str(&datetime.to_rfc3339()))
|
|
||||||
}
|
|
||||||
_ => Err(format!(
|
|
||||||
"Unsupported CEL type for conversion: {:?}",
|
|
||||||
cel_val
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,14 +113,18 @@ pub fn evaluate_cel(expression: &str, context: &JsValue) -> CelResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a CEL expression and return the result as a JavaScript value
|
/// Evaluate a CEL expression and return the result as a string
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn evaluate_cel_js(expression: &str, context: &JsValue) -> Result<JsValue, JsValue> {
|
pub fn evaluate_cel_string(expression: &str, context: &JsValue) -> Result<String, JsValue> {
|
||||||
match evaluate_cel_internal(expression, context) {
|
match evaluate_cel_internal(expression, context) {
|
||||||
Ok(cel_value) => match cel_value_to_js_value(&cel_value) {
|
Ok(cel_value) => {
|
||||||
Ok(js_val) => Ok(js_val),
|
// Convert the result to a reasonable string representation
|
||||||
Err(e) => Err(JsValue::from_str(&format!("Conversion error: {}", e))),
|
let result_string = match &cel_value {
|
||||||
},
|
Value::String(s) => s.clone(),
|
||||||
|
_ => format!("{:?}", cel_value).into(),
|
||||||
|
};
|
||||||
|
Ok(result_string.to_string())
|
||||||
|
}
|
||||||
Err(e) => Err(JsValue::from_str(&e)),
|
Err(e) => Err(JsValue::from_str(&e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user