Celly 0.2.0
See the version list below for details.
dotnet add package Celly --version 0.2.0
NuGet\Install-Package Celly -Version 0.2.0
<PackageReference Include="Celly" Version="0.2.0" />
<PackageVersion Include="Celly" Version="0.2.0" />
<PackageReference Include="Celly" />
paket add Celly --version 0.2.0
#r "nuget: Celly, 0.2.0"
#:package Celly@0.2.0
#addin nuget:?package=Celly&version=0.2.0
#tool nuget:?package=Celly&version=0.2.0
Celly
A native C#/.NET implementation of Google's Common Expression Language (CEL).
Celly is written from scratch in pure managed C# — no WASM shims, no Go-compiled artifacts, no native library bindings.
✅ Conformance: 2,456 / 2,456 (100%) of the official cel-spec conformance suite (30 testdata files, pinned @
59505c1), verified in CI on Linux, Windows, and macOS.
📖 Documentation: bsid.io/celly — user guide plus a deep-dive internals track explaining how the lexer, parser, macros, type checker, evaluator, and protobuf integration work.
Why Celly?
CEL is the expression language behind Kubernetes admission policies (ValidatingAdmissionPolicy), Envoy RBAC, Google Cloud IAM conditions, gRPC protovalidate, and more. Official implementations exist for Go, C++, Java, and Rust — but not .NET. Celly fills that gap with a conformance-verified native implementation.
using Celly;
using Celly.Checking;
using Celly.Types;
var env = CelEnv.Create(new CelEnvSettings
{
Declarations =
[
new VariableDecl("request", CelType.Map(CelType.String, CelType.Dyn)),
],
});
var program = env.Compile("request.user.startsWith('admin-') && size(request.groups) > 0");
var result = program.Eval(new Dictionary<string, object?>
{
["request"] = new Dictionary<string, object?>
{
["user"] = "admin-alice",
["groups"] = new[] { "ops" },
},
});
// result => BoolValue.True
Packages
| Package | Contents | Dependencies |
|---|---|---|
Celly |
Lexer, parser, macros, type checker, evaluator, standard library, all extension libraries | None |
Celly.Protobuf |
Protobuf types: message construction & field access, well-known types (Timestamp/Duration/Struct/Any/wrappers), enums (legacy int and strong modes), proto2 extensions | Celly, Google.Protobuf |
Use Celly alone to evaluate expressions over .NET dictionaries/lists/primitives; add Celly.Protobuf when your data is protobuf messages.
Feature checklist
- Full standard library: operators with CEL semantics (checked int64/uint64 arithmetic, cross-type numeric comparisons, IEEE doubles),
size/in/indexing, all type conversions with Go-compatible formatting, RE2-semanticsmatches()(via .NET's linear-time NonBacktracking engine), nanosecond-precision timestamps/durations with IANA timezone accessors - Macros:
has,all,exists,exists_one,map,filter(+ two-variable comprehensions) - Type checker: gradual typing with
dyn, parameterized-type unification, container (C.name) resolution, comprehension-variable shadowing per spec - Optionals:
optional.of/ofNonZeroValue/none,a.?b,a[?b],[?e],{?k: v},orValue,optMap/optFlatMap, full optional chaining - Extension libraries (opt-in via
CelEnvSettings.Libraries): strings (incl.formatandstrings.quote), math, encoders (base64), bindings (cel.bind), block (cel.block), two-var comprehensions, proto2 extensions (proto.getExt/hasExt), networking (net.IP/net.CIDR) - Protobuf: message construction with WKT collapse (wrappers → primitives, Struct/Value/ListValue → map/dyn/list), Any pack/unpack with bytewise fallback, presence-aware field-wise message equality, proto2 extension fields, strong-enum mode (
ProtoTypeRegistry.FromFiles(strongEnums: true, …)) where enums are distinct named types — an opt-in the reference Go implementation doesn't offer - First-class ASTs: traversal/inspection tools (
AstTools), lossless conversion to/from the canonicalcel.exprprotos (ParsedExpr/CheckedExprincl. type & reference maps) for caching and cross-implementation interop, and a precedence-aware unparser (AST → source, macros restored to original form) - Thread safety:
CelEnvandCelProgramare immutable; programs are safe for concurrent evaluation
// Extensions are opt-in libraries:
var env = CelEnv.Create(new CelEnvSettings
{
Libraries = [Celly.Extensions.StringsLibrary.Instance, Celly.Extensions.MathLibrary.Instance],
});
env.Compile("'%d apples'.format([math.greatest(3, 7, 5)])").Eval(); // "7 apples"
Building
Requires the .NET 8 SDK. protoc is only needed to refresh vendored conformance data.
dotnet build Celly.sln
dotnet test # unit + conformance suites
tools/vendor-conformance.sh # re-vendor cel-spec protos/testdata (pinned commit)
Conformance methodology
Celly vendors the official suite (30 SimpleTestFile textprotos, pre-encoded to binary at vendoring time since Google.Protobuf C# has no textproto parser). Each of the 2,456 conformance cases is an individual xUnit test. testdata/known-failures.txt is a ratcheting skip-list — a listed test that starts passing fails CI until the list is updated — and it is now empty.
The suite's strong_* enum sections re-run shared expressions under the alternate strong-enum semantics they document (mutually exclusive with the default legacy sections); the harness runs those sections with Celly's strong-enum mode enabled, so both semantics are fully verified.
License
Apache-2.0 (matching the CEL ecosystem).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Celly:
| Package | Downloads |
|---|---|
|
Celly.Protobuf
Protobuf integration for Celly (CEL for .NET): message types, well-known types, enums, and cel.expr AST interop. |
|
|
Celly.Protovalidate
protovalidate for .NET: validate protobuf messages against buf.validate rules, powered by the Celly CEL engine. |
GitHub repositories
This package is not used by any popular GitHub repositories.