Project

cel-rs-rb

0.0
The project is in a healthy, maintained state
Robust Ruby bindings to the Rust CEL implementation using Magnus
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 13.4
~> 3.13
~> 0.22
~> 1.55

Runtime

~> 0.9.128
 Project Readme

cel-rs-rb

Gem Version

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)
# => 60

API 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
  • Hash with keys String|Symbol|Integer|Boolean -> map

CEL -> Ruby

  • null -> nil
  • scalar primitives map naturally
  • bytes -> binary Ruby String
  • timestamp -> Time
  • duration -> CEL::Duration
  • list -> Array
  • map -> Hash

Error classes

  • CEL::Error
  • CEL::ParseError
  • CEL::ExecutionError
  • CEL::TypeError

Thread safety and concurrency

  • Compiled CEL::Program instances 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 rake

This 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.