Supporting extensions?
Wonder how, if at all, this library would support extensions in ways the golang implementation does? We could have the need for the Strings(), how would that best be supported here, if that's interesting?
It looks like these are just CEL functions that are namespaced and not available in the interpreter by default. The biggest missing piece in the library is the ability to namespace functions. You can already write your own functions and load them into the interpreter so I'm guessing your questions or more about (1) namespacing, and (2) whether we can provide these extensions out of the box.
I don't have any reservations about supporting this, though I do have several other features and PR reviews that are spec-compliance-related that I think are higher priority than this. That being said, if you wanted to take a stab at implementing, I'd be more than happy to review.
Yeah :) I was thinking of providing this straight to this crate... Something along side how its done in Go
env, err := cel.NewEnv(Strings())
Tho, unsure about the namespacing? Strings are straight methods on strings... are they not?
Not so all of them, got it!
I haven't dropped the ball on this... I ended up implementing this straight on our usage of this only because I didn't see how to best make this available from an API perspective in a way that's seamless enough quite yet. But in case it can be of any help to anyone, cel::strings on that PR has all initial string extensions.
What about something like:
let ctx = Context::default().with_regex().with_time().with_string()
Or
let ctx = Context::default().add_function_set(functions::strings())
Where add_function_set accepts a trait that just has fn add_functions(&mut Context).
Then we can just expose the extension sets, maybe under a config flags?
@howardjohn I'm currently working on implementing the CEL stdlib with proper overloads. Expect a PR in the couple of days. Once that is done, we'll be able to support these extension (and be open to custom libs) much easier.
@alexsnaps not sure what you have in mind there, but I will say (and maybe it's just my lack of understanding) that the way to configure methods and functions with cel-go is pretty tedious compared to how it works in this crate today. Do you intend to preserve sort of the Rust-type function experience, e.g.:
ctx.add_function("my_func", |a: i64, b: i64| a + b)
That's more of the public API, which I wasn't really talking about here. There I'd be in favor of whatever works best, for some definition of "best". I was actually more thinking of the internals here and how FuncCall resolution works.