cel-rs-rb
Ruby bindings for the Rust cel crate, implemented with Magnus.
Goals
- Ruby-first API over the Rust CEL engine
- Close semantic compatibility with Rust
cel::Program+cel::Context - Ruby variable and function interop
- Thread-safe concurrent execution
- GVL released while CEL evaluation runs
Installation
gem "cel-rs-rb"Usage
require "cel"
context = CEL::Context.build(user: {"name" => "Ada"}, scores: [10, 20, 30]) do |ctx|
ctx.define_function("sum") { |*args| args.sum }
end
program = CEL.compile("sum(scores[0], scores[1], scores[2])")
program.execute(context)
# => 60API mapping
-
CEL.compile(source)->CEL::Program -
CEL::Program.compile(source)->CEL::Program -
CEL::Program#execute(context = nil)-> Ruby value -
CEL::Program#references->{ "variables" => [...], "functions" => [...] } -
CEL::Context.new(empty = false)-> context with builtins (false) or empty (true) CEL::Context#add_variable(name, value)CEL::Context#define_function(name) { |*args| ... }-
CEL::Duration.new(seconds)-> duration value for context variables and duration results
Type support
Ruby -> CEL
-
nil->null -
true/false->bool -
Integer->int -
Float->double -
String/Symbol->string - binary
String(ASCII-8BIT, e.g."abc".b) ->bytes -
Time->timestamp -
CEL::Duration->duration -
Array->list -
Hashwith keysString|Symbol|Integer|Boolean->map
CEL -> Ruby
-
null->nil - scalar primitives map naturally
-
bytes-> binary RubyString -
timestamp->Time -
duration->CEL::Duration -
list->Array -
map->Hash
Error classes
CEL::ErrorCEL::ParseErrorCEL::ExecutionErrorCEL::TypeError
Thread safety and concurrency
- Compiled
CEL::Programinstances can be shared and executed concurrently from multiple Ruby threads with separate execution contexts. - Each thread may pass its own
CEL::Context; context data is mutex-protected and copied into an immutable execution snapshot for each run. - CEL evaluation runs with the Ruby GVL released, so other Ruby threads can keep progressing while a program executes.
- Ruby callbacks from CEL functions temporarily re-acquire the GVL before invoking Ruby code.
Development
Tooling
Uses mise for versions:
[tools]
ruby = "4.0"
rust = "1.96.0"Test + lint
bundle exec rakeThis runs:
-
standard(format/lint) - native extension compile
rspec
CI also runs the test suite on Ruby 3.3, Ruby 3.4, and Ruby 4.0 through Buildkite.
Compatibility notes
- Some CEL value variants (e.g. opaque custom Rust types) cannot be fully marshaled to Ruby and raise
CEL::TypeError. - This project targets broad CEL compatibility, but parity for every Rust-only extension point is still evolving.