中文 | English
Intro
It's designed to be used in ACL (Access Control List) systems, where you need to check if a user has access to a resource.
Expression language
- Literals: string, int, float, bool, nil, list, and map
- Nested lists/maps, plus trailing commas
- Comments:
//and nested/* ... */ - Context lookup with
@path, including quoted field names, integer indexes, negative indexes, computed path segments, and nested@access - Postfix access on any primary expression with
.field/.index - Operators:
!, unary-,+ - * / %,== != < > <= >=,in,&&,||,??, and?: insupports substring, list membership/subset, and map key lookup- Missing access resolves to
nil - Bare identifiers are string values outside
@, and field names inside@ - Default arithmetic keeps exact integer division when possible and promotes to float when needed
- Optional advanced arithmetic extends
+/-to strings, lists, and maps
Example
// Normal case
|| // Or operator
// Special case
Let's break it down:
@req.user.role == 'admin': Check if the user has the role ofadmin.@req.user.id in @record.granted: Check if the user's id is in thegrantedlist of the record.@record.published: Check if the record is published.@record.owner == @req.user.id: Check if the record's owner is the user.
The above example is a simple ACL system that checks if the user has access to a record.
More language details can be found in LANG.md.
Capabilities
Input formats
- JSON is supported in the default build
- YAML and TOML are available as optional input backends
- When a backend is compiled in, the CLI can force it with
--json,--yaml, or--toml
CLI
- Reads the context from
stdinand the expression from argv --check/-cexits with code0for truthy results and1for falsy results--astprints the parsed AST instead of evaluating it--version/-Vprints the version--help/-hprints usage
Rust API
- Parse with
Expr::try_fromor cachedExpr::parse_cached_arc - Evaluate with
Expr::eval - Inspect required context names with
requested_ctx - Check whether an expression is context-independent with
is_ctx_independent
Bindings
- WASM via
wasm-bindgen(docs) - C shared library (docs)
- Python module via PyO3 (docs)
- The library also supports
no_std(withalloc) whenstdis disabled
Usage
Integration
// Parse expr
let expr = "@req.user.name in 'foobar' && @files.0.published == true";
let expr = try_from?;
// Construct context
let ctx_names = expr.requested_ctx; // ["req", "files"]
// You can construct the context indeed, but we use json! for simplicity
let ctx = json!;
// Eval
let result = expr.eval?; // Val::Bool(true)
match result
CLI
|
# Check mode (exit code 0/1)
| &&
# Dump AST
|
Build Bindings
See docs/ for detailed binding documentation.
Ports
License
Apache-2.0 lollipopkit