本地 C# CEL 实现
本地 C#/.NET 实现谷歌的公共表达语言(CEL)。Celly 完全用纯托管 C# 从头编写——没有 WASM 适配器,没有 Go 编译的工件,没有原生库绑定。✅ 兼容性:官方 cel-spec 兼容性套件的 2,456 / 2,456(100%)通过(30 个测试数据文件,固定 @ 59505c1),在 Linux、Windows 和 macOS 上的 CI 中经过验证。状态:1.0——稳定的公共 API(快照测试),100% 兼容,经过模糊测试的。⚡ 性能:与参考 Go 实现在同一水平——在简单表达式上与 cel-go 相差不到 ~1.2×,在重理解的表达式上速度比 cel-go 更快(15 µs 对比 23 µs)。在各个方面都快于 Cel.NET。请参见性能。📖 文档:bsid.io/celly——用户指南加深入的内部追踪,解释词法分析器、解析器、宏、类型检查器、评估器和 protobuf 集成的工作原理。为什么选择 Celly?CEL 是 Kubernetes 准入策略(ValidatingAdmissionPolicy)、Envoy RBAC、谷歌云 IAM 条件、gRPC protovalidate 等的表达语言。Go、C++、Java 和 Rust 已有官方实现——但 .NET 没有。Celly 用经过兼容性验证的原生实现填补了这一空白。使用 Celly; 使用 Celly.Checking; 使用 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 包及内容 依赖关系 Celly 词法分析器、解析器、宏、类型检查器、评估器、标准库、所有扩展库 无 Celly.Protobuf Protobuf 类型:消息构建和字段访问,已知类型(Timestamp/Duration/Struct/Any/wrappers),枚举(遗留 int 和强模式),proto2 扩展 Celly , Google.Protobuf 单独使用 Celly 评估 .NET 字典/列表/原始类型上的表达式;当您的数据是 protobuf 消息时,添加 Celly.Protobuf。 特性清单 - 完整的标准库:具有 CEL 语义的运算符(检查的 int64/uint64 算术,跨类型数字比较,IEEE 双精度数),size / in / 索引,所有与 Go 兼容格式的类型转换,RE2 语义匹配()(通过 .NET 的线性时间非回溯引擎),纳秒级精度的时间戳/持续时间,使用 IANA 时区访问器 - 宏:has,all,exists,exists_one,map,filter(+ 两变量理解) - 类型检查器:使用 dyn 的渐进式类型,参数化类型统一,容器 (C.name) 解析,按规范理解变量遮蔽 - 可选值:optional.of/ofNonZeroValue/none,a.?b,a[?b],[?e],{?k: v},orValue,optMap / optFlatMap,完整的可选链 - 扩展库(通过 CelEnvSettings.Libraries 可选启用):字符串(包括格式和 strings.quote)、数学、编码器(base64)、绑定(cel.bind)、块(cel.block)、双变量理解、proto2 扩展(proto.getExt/hasExt)、网络(net.IP / net.CIDR) - Protobuf:使用 WKT 合并的消息构建(wrappers → 原始类型,Struct/Value/ListValue → map/dyn/list),Any 打包/解包带字节级后备,存在感知字段消息相等性,proto2 扩展字段,强枚举模式(ProtoTypeRegistry.FromFiles(strongEnums: true, …)),其中枚举是不同命名类型是可选的,参考 Go 实现没有提供 - 原生 .NET 类型:NativeTypeProvider 赋予您的类/记录/枚举完整的 CEL 语义——构造、通过检查程序的类型字段访问,has() 存在,snake_case 字段别名,Nullable<T> 作为包装,无需 protobuf - 一流的 AST:遍历/检查工具(AstTools),对从标准 cel.expr protos(ParsedExpr / CheckedExpr 包括类型和引用映射)进行无损转换的缓存和跨实现互操作性,以及优先级感知的 unparser(AST → 源,宏恢复为原始形式) - 线程安全:CelEnv 和 CelProgram 是不可变的;程序可以安全并发评估 // 扩展是可选启用库: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" 构建 需要 .NET 8 SDK。protoc 仅用于刷新供应商兼容性数据。dotnet build Celly.sln dotnet test # 单元 + 兼容性套件 tools/vendor-conformance.sh # 重新供应 cel-spec protos/testdata(固定提交) 兼容性方法 Celly 供应官方套件(30 个 SimpleTestFile 文本协议,在供应时预编码为二进制,因为 Google.Protobuf C# 没有文本协议解析器)。每个 2,456 个兼容性案例都是单独的 xUnit 测试。testdata/known-failures.txt 是一个逐步跳过列表——列出
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡