A parser for Google's Common Expression Language (CEL) that produces a detailed Abstract Syntax Tree (AST).
Add the following to your Cargo.toml:
[dependencies]
rust-cel-parser = "0.1.0" # Replace with the latest versionuse rust_cel_parser::{parse_cel_program, Expr, BinaryOperator, Literal};
fn main() {
let expression = "request.auth.claims['group'] == 'admin'";
let ast = parse_cel_program(expression).unwrap();
// Inspect the AST using helper methods
if let Some((op, _, right)) = ast.as_binary_op() {
assert_eq!(op, BinaryOperator::Eq);
assert_eq!(right.as_literal(), Some(&Literal::String("admin".to_string())));
println!("Successfully parsed and validated the expression!");
}
}The Visitor pattern is a way to analyze an expression. Here's how to find all unique identifiers used in an expression:
use rust_cel_parser::{parse_cel_program, visitor::Visitor};
use std::collections::HashSet;
// 1. Define a struct to hold your state.
struct IdentifierCollector<'a> {
names: HashSet<&'a str>,
}
// 2. Implement the Visitor trait, overriding only the methods you need.
impl<'ast> Visitor<'ast> for IdentifierCollector<'ast> {
fn visit_identifier(&mut self, ident: &'ast str) {
self.names.insert(ident);
}
}
// 3. Run the visitor.
let ast = parse_cel_program("request.user + params.id").unwrap();
let mut collector = IdentifierCollector { names: HashSet::new() };
ast.accept(&mut collector); // The `accept` method starts the traversal.
assert!(collector.names.contains("request"));
assert!(collector.names.contains("params"));
println!("Found identifiers: {:?}", collector.names);This parser supports a significant portion of the CEL specification.
- Literals:
int,uint,double,bool,string,bytes,null. - Operators: All arithmetic, logical, and relational operators with correct precedence.
- Data Structures:
List([...]),Map({...}), andMessageliterals. - Accessors: Field access (
.), index access ([...]). - Control Flow: Ternary operator (
_ ? _ : _). - Macros:
has(),all(),exists(),exists_one(),filter(),map().
This project is licensed under the MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
Contributions are welcome! Please see CONTRIBUTING.md for details on how to set up the development environment, run tests, and submit a pull request.