A type-safe Rust library for Common Expression Language (CEL), built on top of cel-cpp with zero-cost FFI bindings via cxx.
- English Documentation - Complete documentation and guides
- 中文文档 - 中文文档和指南
For detailed guides on architecture, function registration, type system, and advanced features, see the documentation directory.
Add to your Cargo.toml:
[dependencies]
cel-cxx = "0.2.3"
# Optional features
cel-cxx = { version = "0.2.3", features = ["tokio"] }use cel_cxx::*;
// 1. Build environment with variables and functions
let env = Env::builder()
.declare_variable::<String>("name")?
.declare_variable::<i64>("age")?
.register_global_function("adult", |age: i64| age >= 18)?
.build()?;
// 2. Compile expression
let program = env.compile("'Hello ' + name + '! You are ' + (adult(age) ? 'an adult' : 'a minor')")?;
// 3. Create activation with variable bindings
let activation = Activation::new()
.bind_variable("name", "Alice")?
.bind_variable("age", 25i64)?;
// 4. Evaluate
let result = program.evaluate(&activation)?;
println!("{}", result); // "Hello Alice! You are an adult"
# Ok::<(), cel_cxx::Error>(())use cel_cxx::*;
#[derive(Opaque, Debug, Clone, PartialEq)]
// Specify type name in CEL type system.
#[cel_cxx(type = "myapp.User")]
// Generates `std::fmt::Display` impl for User` with `Debug` trait.
#[cel_cxx(display)]
// or you can specify a custom format.
// Generates `std::fmt::Display` impl with custom format.
#[cel_cxx(display = write!(fmt, "User(name={name})", name = &self.name))]
struct User {
name: String,
age: i32,
roles: Vec<String>,
}
impl User {
// Struct methods can be registered directly as CEL member functions
fn has_role(&self, role: &str) -> bool {
self.roles.contains(&role.to_string())
}
fn is_adult(&self) -> bool {
self.age >= 18
}
fn get_role_count(&self) -> i64 {
self.roles.len() as i64
}
}
let env = Env::builder()
.declare_variable::<User>("user")?
// ✨ Register struct methods directly - &self becomes CEL receiver
.register_member_function("has_role", User::has_role)?
.register_member_function("is_adult", User::is_adult)?
.register_member_function("get_role_count", User::get_role_count)?
.build()?;
let program = env.compile("user.has_role('admin') && user.is_adult()")?;
# Ok::<(), cel_cxx::Error>(())| Platform | Target Triple | Status | Notes |
|---|---|---|---|
| Linux | x86_64-unknown-linux-gnu |
✅ | Tested |
aarch64-unknown-linux-gnu |
✅ | Tested | |
armv7-unknown-linux-gnueabi |
✅ | Tested via cross-rs | |
i686-unknown-linux-gnu |
✅ | Tested via cross-rs | |
| Windows | x86_64-pc-windows-msvc |
✅ | Tested (Visual Studio 2022+) |
| macOS | x86_64-apple-darwin |
✅ | Tested |
aarch64-apple-darwin |
✅ | Tested | |
arm64e-apple-darwin |
✅ | Tested | |
| Android | aarch64-linux-android |
🟡 | Should work, use cargo-ndk |
armv7-linux-androideabi |
🟡 | Should work, use cargo-ndk | |
x86_64-linux-android |
🟡 | Should work, use cargo-ndk | |
i686-linux-android |
🟡 | Should work, use cargo-ndk | |
| iOS | aarch64-apple-ios |
🟡 | Should work, untested |
aarch64-apple-ios-sim |
🟡 | Should work, untested | |
x86_64-apple-ios |
🟡 | Should work, untested | |
arm64e-apple-ios |
🟡 | Should work, untested | |
| tvOS | aarch64-apple-tvos |
🟡 | Should work, untested |
aarch64-apple-tvos-sim |
🟡 | Should work, untested | |
x86_64-apple-tvos |
🟡 | Should work, untested | |
| watchOS | aarch64-apple-watchos |
🟡 | Should work, untested |
aarch64-apple-watchos-sim |
🟡 | Should work, untested | |
x86_64-apple-watchos-sim |
🟡 | Should work, untested | |
arm64_32-apple-watchos |
🟡 | Should work, untested | |
armv7k-apple-watchos |
🟡 | Should work, untested | |
| visionOS | aarch64-apple-visionos |
🟡 | Should work, untested |
aarch64-apple-visionos-sim |
🟡 | Should work, untested | |
| WebAssembly | wasm32-unknown-emscripten |
✅ | Tested via cross-rs |
Legend:
- ✅ Tested: Confirmed working with automated tests
- 🟡 Should work: Build configuration exists but not tested in CI
cel-cxx includes built-in support for cross-compilation via cross-rs. The build system automatically detects cross-compilation environments and configures the appropriate toolchains.
Usage with cross-rs:
# Install cross-rs
cargo install cross --git https://github.com/cross-rs/cross
# Build for aarch64
cross build --target aarch64-unknown-linux-gnuNote: Not all cross-rs targets are supported due to CEL-CPP's build requirements. musl targets and some embedded targets may not work due to missing C++ standard library support or incompatible toolchains.
Android builds require additional setup beyond the standard Rust toolchain:
Prerequisites:
- Install Android NDK and set
ANDROID_NDK_HOME - Install
cargo-ndkfor simplified Android builds
# Install cargo-ndk
cargo install cargo-ndk
# Add Android targets
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add x86_64-linux-android
rustup target add i686-linux-androidBuilding for Android:
# Build for ARM64 (recommended)
cargo ndk --target aarch64-linux-android build
# Build for ARMv7
cargo ndk --target armv7-linux-androideabi build
# Build for x86_64 (emulator)
cargo ndk --target x86_64-linux-android build
# Build for i686 (emulator)
cargo ndk --target i686-linux-android buildWhy cargo-ndk is required:
ANDROID_NDK_HOMEconfigures Bazel for CEL-CPP compilationcargo-ndkautomatically sets upCC_{target}andAR_{target}environment variables needed for the Rust FFI layer- This ensures both the C++ (CEL-CPP) and Rust (cel-cxx-ffi) components use compatible toolchains
| Feature | Status | Description |
|---|---|---|
| Basic Types | ✅ | null, bool, int, uint, double, string, bytes |
| Collections | ✅ | list<T>, map<K,V> with full indexing and comprehensions |
| Time Types | ✅ | duration, timestamp with full arithmetic support |
| Operators | ✅ | Arithmetic, logical, comparison, and membership operators |
| Variables | ✅ | Variable binding and scoping |
| Conditionals | ✅ | Ternary operator and logical short-circuiting |
| Comprehensions | ✅ | List and map comprehensions with filtering |
| Custom Types | ✅ | Opaque types via #[derive(Opaque)] |
| Protobuf Message Type | 🚧 Planned | Direct support for protobuf messages and enums as native CEL types with field access (e.g., p.x). See issue #1 |
| Macros | ✅ | CEL macro expansion support |
| Function Overloads | ✅ | Multiple function signatures with automatic resolution |
| Type Checking | ✅ | Compile-time type validation |
| Feature | Status | Description |
|---|---|---|
| Built-in Functions | ✅ | Core CEL functions: size(), type(), has(), etc. |
| String Functions | ✅ | contains(), startsWith(), endsWith(), matches() |
| List Functions | ✅ | all(), exists(), exists_one(), filter(), map() |
| Map Functions | ✅ | Key/value iteration and manipulation |
| Type Conversion | ✅ | int(), double(), string(), bytes(), duration(), timestamp() |
| Math Functions | ✅ | Basic arithmetic and comparison operations |
| Feature | Status | Description |
|---|---|---|
| Optional Types | ✅ | optional<T> with safe navigation and null handling |
| Safe Navigation | ✅ | ?. operator for safe member access |
| Optional Chaining | ✅ | Chain optional operations without explicit null checks |
| Value Extraction | ✅ | value() and hasValue() functions for optional handling |
| Optional Macros | ✅ | optional.of(), optional.ofNonZeroValue() macros |
| Extension | Status | Description |
|---|---|---|
| Strings Extension | ✅ | Advanced string operations: split(), join(), replace(), format() |
| Math Extension | ✅ | Mathematical functions: math.greatest(), math.least(), math.abs(), math.sqrt(), bitwise ops |
| Lists Extension | ✅ | Enhanced list operations: flatten(), reverse(), slice(), unique() |
| Sets Extension | ✅ | Set operations: sets.contains(), sets.equivalent(), sets.intersects() |
| Regex Extension | ✅ | Regular expression support: matches(), findAll(), split() |
| Encoders Extension | ✅ | Encoding/decoding: base64.encode(), base64.decode(), URL encoding |
| Bindings Extension | ✅ | Variable binding and scoping enhancements |
| Feature | Status | Description |
|---|---|---|
| Custom Functions | ✅ | Register custom Rust functions with automatic type conversion |
| Async Support | ✅ | Async function calls and evaluation with Tokio integration |
| Custom Extensions | ✅ | Build and register custom CEL extensions |
| Performance Optimization | ✅ | Optimized evaluation with caching and short-circuiting |
Licensed under the Apache License 2.0. See LICENSE for details.
google/cel-cpp- The foundational C++ CEL implementationdtolnay/cxx- Safe and efficient Rust-C++ interoprmanoka/async-scoped- Scoped async execution for safe lifetime management- The CEL community and other Rust CEL implementations for inspiration and ecosystem growth