clarkmcc / cel-rust

Common Expression Language interpreter written in Rust
https://crates.io/crates/cel-interpreter
MIT License
360 stars 16 forks source link

Constructing rust types in cel #73

Open obsoleszenz opened 1 month ago

obsoleszenz commented 1 month ago

From the cle doc it seems like it's possible to construct strongly typed types inside cel and pass them back. Does cel-rust support this? Couldn't find documentation about this.

Example:

use cel_interpreter::{Context, Program};
use serde::Serialize;

// An example struct that derives Serialize
#[derive(Serialize)]
struct MyStruct {
    a: i32,
    b: i32,
}

fn main() {
    let program = Program::compile("MyStruct { a: 0, b: 0}").unwrap();
    let context = Context::default();

    let value = program.execute(&context).unwrap();
    assert_eq!(value, true.into());
    println!("{value:?}");
}

image

clarkmcc commented 1 month ago

This is not supported today. I believe the cel-go project supports this via protobufs. It's definitely something that we need to support to be spec-compliant.

zeroexcuses commented 1 month ago

Is there a easy way to hack this so that in addition to Json, we also support Ron ? That might be a solution to this.

Context: I am currently using Ron for my config files -- but I find what I really want is not merely Ron, but EXPRESSIONS over Ron -- which led me to finding Cel. And I'm now wondering if there is a easy hack to make Cel-rust also support Ron in addition to Json for the data notation.

clarkmcc commented 1 month ago

@zeroexcuses any type that implements Serialize (which a Rust ron rust would) can be added as a variable to the context. Not every rust data type is supported (tuples for example), so those wouldn't be available in your expressions, but the CEL-supported types should work fine.

Are you having issues doing the following? Or is your question about deserializing from CEL to Ron?

use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize, Serialize)]
struct MyStruct {
    boolean: bool,
    float: f32,
}

let x: MyStruct = ron::from_str("(boolean: true, float: 1.23)").unwrap();
let mut context = Context::default();
context.add_variable("x", x).unwrap();
Jikstra commented 1 month ago

Is there a easy way to hack this so that in addition to Json, we also support Ron ? That might be a solution to this.

Context: I am currently using Ron for my config files -- but I find what I really want is not merely Ron, but EXPRESSIONS over Ron -- which led me to finding Cel. And I'm now wondering if there is a easy hack to make Cel-rust also support Ron in addition to Json for the data notation.

This is also what i want/need. I started hacking expressions into my rust types, which kinda works but also is hacky. I think fusing cel and the ron syntax for enums/structs would be quite neat. I could imagine that one could return strings from cel and then deserialize them on the rust side to get rust types. Maybe that's the hack you are looking for?

clarkmcc commented 1 month ago

Can you help me understand the idea behind coupling Ron and cel? Cel is format-agnostic. Anything that implements serialize can be referenced in a CEL expression already.

Jikstra commented 1 month ago

Can you help me understand the idea behind coupling Ron and cel? Cel is format-agnostic. Anything that implements serialize can be referenced in a CEL expression already.

I'm more talking about deserializing. Being able to construct rust structs/enums from cel would be amazing and leveraging the ron syntax for this.