moonrule

    An explainable expression rules engine for JSON data, implemented in MoonBit.

    rules
    validation
    json
    expression
    policy
    Download zip
    Author
    Version
    0.4.1
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    25

    Dependencies

    #MoonRule

    MoonRule 是一个使用 MoonBit 实现的轻量、可解释动态规则引擎。它将规则表达式编译为可复用的程序,并在 JSON 数据上执行,适用于 API 准入、表单校验、配置检查和 CI 质量门禁。

    项目当前面向 MoonBit 0.10.4,核心库支持 MoonBit 的多后端;命令行工具提供基于文件的批量校验和 JSON 报告。

    #主要能力

    • 词法分析、优先级解析和不可变 AST
    • JSON 对象字段、数组索引、嵌套路径和 ?. / ?[...] 可选访问
    • 算术、比较、布尔短路和集合成员运算
    • 字符串、数组、对象和正则表达式内置函数
    • 一次编译、多次执行
    • 多规则批量校验
    • 稳定的诊断代码、源码范围和修复提示
    • 确定性的逐步执行轨迹
    • 面向不可信规则文本的源码长度、AST 节点数和嵌套深度限制
    • 面向运行阶段的最大执行步数限制
    • 静态分析:依赖路径、函数调用、复杂度与不可达分支
    • 严重级别策略、快速失败与多数据批量校验
    • 日期时间、IPv4、邮箱、UUID 和 SemVer 等确定性业务校验
    • 25 个内置函数及可供编辑器读取的函数目录
    • 可配置的静态分析准入策略和 CI 门禁
    • JSON 驱动的规则回归测试套件及精确失败规则断言
    • 适合 CI 的 JSON 报告和退出码
    • 黑盒测试、白盒测试、基准测试和 GitHub Actions

    #快速开始

    单条规则:

    ///|
    test "README quick start" {
    let input : Json = {
    "user": { "age": 24, "country": "CN", "roles": ["editor"], "active": true },
    }
    let result = check(
    "user.age >= 18 && user.country in [\"CN\", \"SG\"] && user.active", input,
    )
    assert_eq(result, Ok(true))
    }

    规则只编译一次,然后可以处理多份数据:

    ///|
    test "README compile once" {
    let program = compile("order.total > 0 && order.currency == \"CNY\"").unwrap()
    assert_eq(
    evaluate(program, { "order": { "total": 99, "currency": "CNY" } }),
    Ok(Json::boolean(true)),
    )
    }

    编译外部规则时可显式收紧资源限制:

    ///|
    test "README defensive compile limits" {
    let limits : CompileLimits = {
    max_source_length: 4096,
    max_ast_nodes: 1024,
    max_ast_depth: 64,
    }
    let program = compile_with_limits("user.active", limits).unwrap()
    assert_true(program.node_count() > 0)
    assert_true(program.ast_depth() > 0)
    }

    多规则报告:

    ///|
    test "README ruleset" {
    let rules = RuleSet::compile([
    RuleDefinition::new("adult", "user.age >= 18", "The user must be an adult."),
    RuleDefinition::new("active", "user.active", "The account must be active."),
    ]).unwrap()
    let report = rules.evaluate({ "user": { "age": 20, "active": true } })
    assert_true(report.passed)
    assert_eq(report.passed_count, 2)
    }

    缺失字段较常见时,可选访问返回 null,再由 coalesce 提供默认值:

    ///|
    test "README optional validation" {
    let rule = "is_email(coalesce(request?.user?.email, \"\"))"
    assert_eq(check(rule, Json::empty_object()), Ok(false))
    assert_eq(
    check(rule, { "request": { "user": { "email": "dev@example.com" } } }),
    Ok(true),
    )
    }

    #命令行

    验证示例数据:

    moon run cmd/main -- check examples/access-rules.json examples/user-valid.json

    失败报告会返回退出码 1,配置、解析或运行错误返回 2:

    moon run cmd/main -- check examples/access-rules.json examples/user-invalid.json

    完整的 API 请求校验示例:

    moon run cmd/main -- lint-rules examples/api-validation-rules.json moon run cmd/main -- check examples/api-validation-rules.json examples/api-request-valid.json moon run cmd/main -- check examples/api-validation-rules.json examples/api-request-invalid.json moon run cmd/main -- test-rules examples/api-validation-rules.json examples/api-validation-cases.json

    解释一条规则的每个求值步骤:

    moon run cmd/main -- explain-file \ "user.age >= 18 && user.active" \ examples/user-valid.json

    完整命令:

    moonrule eval <expression> <json> moonrule eval-file <expression> <data.json> moonrule explain <expression> <json> moonrule explain-file <expression> <data.json> moonrule analyze <expression> moonrule analyze-rules <rules.json> moonrule lint <expression> moonrule lint-rules <rules.json> moonrule test-rules <rules.json> <cases.json> moonrule check <rules.json> <data.json> moonrule check-batch <rules.json> <data-array.json> moonrule functions

    #表达式语言

    类别语法
    字面量true、false、null、数字、字符串、数组
    路径user.name、orders[0].total、meta["key"]
    可选访问user?.profile?.email、items?[0]
    算术+、-、*、/、%
    比较==、!=、<、<=、>、>=
    布尔!、&&、||
    成员value in array、key in object、part in string

    运算符从高到低依次为:一元运算、乘除余数、加减、顺序比较、相等比较、&&、||。

    内置函数:

    函数说明
    len(value)返回字符串字符数、数组长度或对象字段数
    contains(container, value)检查字符串、数组或对象
    starts_with(text, prefix)检查字符串前缀
    ends_with(text, suffix)检查字符串后缀
    lower(text) / upper(text)ASCII/Unicode大小写转换
    abs(number)数值绝对值
    matches(text, pattern)正则表达式匹配
    exists(value)判断值不是 null
    has(object, key)判断对象是否包含字段
    get(object, key, default)安全读取字段,缺失时返回默认值
    min / max / clamp / sum常用数值与数组聚合
    type_of(value) / coalesce(...)类型识别与空值回退
    all(booleans) / any(booleans)布尔数组聚合
    is_date(text) / is_datetime(text)ISO 日期与 RFC 3339 时间戳校验
    is_ipv4(text) / is_email(text)IPv4 地址与常用邮箱地址校验
    is_uuid(text) / is_semver(text)标准 UUID 与语义化版本校验

    MoonRule 使用严格类型语义:布尔运算不会隐式转换数字或字符串;普通字段访问缺失、类型不匹配、越界和除零均返回结构化诊断。可选访问只把缺失字段、空值和越界转换为 null,不会掩盖类型错误。

    #规则配置

    check 命令接收一个 JSON 规则数组:

    [ { "name": "adult-user", "expression": "user.age >= 18", "message": "The user must be at least 18 years old.", "severity": "Error" } ]

    severity 可取 Info、Warning 或 Error。当前版本会执行全部规则并完整报告结果,不会因第一条失败而停止。

    #规则回归测试

    回归套件是一个 JSON 数组。每个案例包含稳定名称、完整输入、预期是否通过,以及可选的精确失败规则集合:

    [ { "name": "minor user", "input": { "user": { "age": 15 } }, "expected_passed": false, "expected_failed_rules": ["adult-user"] } ]

    test-rules 会复用已编译规则运行全部案例。全部预期匹配时返回 0,存在不匹配时返回 1,规则或套件配置错误返回 2。报告同时保留逐规则结果和运行诊断,适合直接存档为 CI 构件。

    #开发与验证

    moon check --deny-warn moon test --package YeeHh2004/moonrule --deny-warn moon bench moon coverage analyze moon coverage report moon info moon package --list

    项目设计、语法边界和验收记录见:

    #当前边界

    • 标识符暂限定为 ASCII 字母、数字和下划线
    • 不提供循环、赋值、文件访问或任意函数调用
    • matches 遵循 MoonBit 正则表达式语法,并限制模式及输入长度
    • 普通字段访问缺失仍是错误;需要空值语义时必须显式使用 ?. 或 ?[...]
    • 日期时间与网络格式函数只校验传入文本,不读取时钟、网络或外部状态

    #许可证

    Apache License 2.0。详见 LICENSE。

    AnalysisFinding

    pub(all) struct AnalysisFinding {
    level : AnalysisLevel
    code : String
    message : String
    span : Span
    hint : String?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    One actionable observation produced without evaluating input data.

    AnalysisGateReport

    pub(all) struct AnalysisGateReport {
    passed : Bool
    analysis : ProgramAnalysis
    violations : Array[AnalysisFinding]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Static analysis plus the policy violations that determine CI acceptance.

    AnalysisGateReport::to_json_string

    fn AnalysisGateReport::to_json_string(self : AnalysisGateReport, indent? : Int) -> String

    AnalysisLevel

    pub(all) enum AnalysisLevel {
    Note
    Warning
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Importance of a static-analysis finding.

    AnalysisPolicy

    pub(all) struct AnalysisPolicy {
    max_ast_nodes : Int
    max_ast_depth : Int
    max_estimated_cost : Int
    reject_warnings : Bool
    allow_dynamic_regex : Bool
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    CI-oriented limits applied to the result of static program analysis.

    AnalysisPolicy::default

    BatchItemReport

    pub(all) struct BatchItemReport {
    index : Int
    passed : Bool
    report : PolicyReport
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Result for one zero-based input record.

    BatchOptions

    pub(all) struct BatchOptions {
    rule_options : RuleEvaluationOptions
    stop_on_first_rejected_record : Bool
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Options for applying the same compiled rules to several JSON records.

    BatchOptions::default

    fn BatchOptions::default() -> BatchOptions

    BatchReport

    pub(all) struct BatchReport {
    passed : Bool
    requested_count : Int
    evaluated_count : Int
    accepted_count : Int
    rejected_count : Int
    stopped_early : Bool
    items : Array[BatchItemReport]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Aggregate result for a batch validation operation.

    BatchReport::to_json_string

    fn BatchReport::to_json_string(self : BatchReport, indent? : Int) -> String

    BinaryOp

    pub enum BinaryOp {
    Or
    And
    Equal
    NotEqual
    Less
    LessEqual
    Greater
    GreaterEqual
    In
    Add
    Subtract
    Multiply
    Divide
    Remainder
    } derive(
    Debug
    )

    CompileLimits

    pub(all) struct CompileLimits {
    max_source_length : Int
    max_ast_nodes : Int
    max_ast_depth : Int
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Defensive limits applied while compiling untrusted rule text.

    CompileLimits::default

    fn CompileLimits::default() -> CompileLimits

    Conservative defaults suitable for API and CI use.

    CompiledRule

    pub struct CompiledRule {
    definition : RuleDefinition
    program : Program
    }

    Diagnostic

    pub(all) struct Diagnostic {
    stage : DiagnosticStage
    code : String
    message : String
    span : Span
    hint : String?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    A stable, structured error intended for editors, CLIs, and CI reports.

    Diagnostic::new

    fn Diagnostic::new(stage : DiagnosticStage, code : String, message : String, span : Span, hint? : String) -> Diagnostic

    Diagnostic::render

    fn Diagnostic::render(self : Diagnostic, source : String) -> String

    DiagnosticStage

    pub(all) enum DiagnosticStage {
    Lex
    Parse
    Evaluate
    Configure
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    The stage that produced a diagnostic.

    EvaluationLimits

    pub(all) struct EvaluationLimits {
    max_steps : Int
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Limits applied while executing a compiled rule.

    The step budget makes evaluation time predictable for rules accepted from external users. A step is consumed whenever an AST node is visited.

    EvaluationLimits::default

    A conservative budget that is far above ordinary API validation rules.

    EvaluationTrace

    pub(all) struct EvaluationTrace {
    value : Json
    steps : Array[TraceStep]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    The result and ordered steps from an explained evaluation.

    EvaluationTrace::to_json_string

    fn EvaluationTrace::to_json_string(self : EvaluationTrace, indent? : Int) -> String

    Expr

    pub enum Expr {
    Literal(Json, Span)
    Variable(String, Span)
    ArrayLiteral(Array[Expr], Span)
    Member(Expr, String, Span)
    Index(Expr, Expr, Span)
    OptionalMember(Expr, String, Span)
    OptionalIndex(Expr, Expr, Span)
    Call(String, Array[Expr], Span)
    Unary(UnaryOp, Expr, Span)
    Binary(Expr, BinaryOp, Expr, Span)
    } derive(
    Debug
    )

    ExpressionStatistics

    pub(all) struct ExpressionStatistics {
    literals : Int
    variables : Int
    arrays : Int
    members : Int
    indexes : Int
    optional_members : Int
    optional_indexes : Int
    calls : Int
    unary_operations : Int
    binary_operations : Int
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Counts for the expression forms contained in a compiled program.

    FailureThreshold

    pub(all) enum FailureThreshold {
    AnyFailure
    WarningOrHigher
    ErrorOnly
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Minimum severity that makes a failed rule reject an input.

    FunctionCategory

    pub(all) enum FunctionCategory {
    Collection
    String
    Number
    Conversion
    Predicate
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Broad grouping used by generated documentation and editor integrations.

    FunctionSpec

    pub(all) struct FunctionSpec {
    name : String
    category : FunctionCategory
    min_arguments : Int
    max_arguments : Int
    signature : String
    summary : String
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Machine-readable description of a function built into MoonRule.

    Keeping this metadata in the library lets command-line tools and web editors provide completion without maintaining a second function list.

    FunctionSpec::accepts_arity

    fn FunctionSpec::accepts_arity(self : FunctionSpec, arguments : Int) -> Bool

    Return true when an argument count is accepted by a function specification.

    FunctionSpec::arity_description

    fn FunctionSpec::arity_description(self : FunctionSpec) -> String

    Render a concise argument-count description for diagnostics.

    OutcomeStatus

    pub(all) enum OutcomeStatus {
    Passed
    Failed
    EvaluationError
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    PolicyReport

    pub(all) struct PolicyReport {
    passed : Bool
    evaluated_count : Int
    passed_count : Int
    failed_count : Int
    blocking_count : Int
    advisory_count : Int
    error_count : Int
    stopped_early : Bool
    outcomes : Array[RuleOutcome]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Result of evaluating a rule set with an explicit acceptance policy.

    PolicyReport::to_json_string

    fn PolicyReport::to_json_string(self : PolicyReport, indent? : Int) -> String

    Program

    pub struct Program {
    root : Expr
    source : String
    node_count : Int
    ast_depth : Int
    }

    A compiled expression. Its representation is intentionally opaque so the parser can evolve without breaking consumers.

    Program::ast_depth

    fn Program::ast_depth(self : Program) -> Int

    Maximum nesting depth of the compiled abstract syntax tree.

    Program::node_count

    fn Program::node_count(self : Program) -> Int

    Number of nodes in the compiled abstract syntax tree.

    Program::source

    fn Program::source(self : Program) -> String

    Program::span

    fn Program::span(self : Program) -> Span

    ProgramAnalysis

    pub(all) struct ProgramAnalysis {
    source_length : Int
    node_count : Int
    ast_depth : Int
    estimated_cost : Int
    statistics : ExpressionStatistics
    referenced_paths : Array[String]
    called_functions : Array[String]
    findings : Array[AnalysisFinding]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Static description of a compiled MoonRule program.

    ProgramAnalysis::findings_at

    Select findings of one importance level while preserving source order.

    ProgramAnalysis::has_warnings

    fn ProgramAnalysis::has_warnings(self : ProgramAnalysis) -> Bool

    Return true when static analysis found at least one warning.

    ProgramAnalysis::is_clean

    fn ProgramAnalysis::is_clean(self : ProgramAnalysis) -> Bool

    Return true when analysis produced no notes or warnings.

    ProgramAnalysis::note_count

    fn ProgramAnalysis::note_count(self : ProgramAnalysis) -> Int

    ProgramAnalysis::references_path

    fn ProgramAnalysis::references_path(self : ProgramAnalysis, path : String) -> Bool

    Test whether the exact normalized JSON path is referenced.

    ProgramAnalysis::to_json_string

    fn ProgramAnalysis::to_json_string(self : ProgramAnalysis, indent? : Int) -> String

    ProgramAnalysis::uses_function

    fn ProgramAnalysis::uses_function(self : ProgramAnalysis, name : String) -> Bool

    Test whether the program calls a named built-in or unresolved function.

    ProgramAnalysis::warning_count

    fn ProgramAnalysis::warning_count(self : ProgramAnalysis) -> Int

    RuleAnalysisGate

    pub(all) struct RuleAnalysisGate {
    name : String
    severity : Severity
    report : AnalysisGateReport
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Gate result associated with one named rule.

    RuleDefinition

    pub(all) struct RuleDefinition {
    name : String
    expression : String
    message : String
    severity : Severity
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Serializable source configuration for one rule.

    RuleDefinition::new

    fn RuleDefinition::new(name : String, expression : String, message : String, severity? : Severity) -> RuleDefinition

    RuleEvaluationOptions

    pub(all) struct RuleEvaluationOptions {
    failure_threshold : FailureThreshold
    stop_on_blocking_failure : Bool
    stop_on_evaluation_error : Bool
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Controls severity handling and early termination for a rule-set evaluation.

    RuleEvaluationOptions::default

    RuleOutcome

    pub(all) struct RuleOutcome {
    name : String
    status : OutcomeStatus
    message : String
    severity : Severity
    diagnostic : Diagnostic?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    RuleProgramAnalysis

    pub(all) struct RuleProgramAnalysis {
    name : String
    severity : Severity
    expression : String
    analysis : ProgramAnalysis
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Static-analysis result associated with one named rule definition.

    RuleReport

    pub(all) struct RuleReport {
    passed : Bool
    passed_count : Int
    failed_count : Int
    error_count : Int
    outcomes : Array[RuleOutcome]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    RuleReport::to_json_string

    fn RuleReport::to_json_string(self : RuleReport, indent? : Int) -> String

    RuleSet

    pub struct RuleSet {
    rules : Array[CompiledRule]
    }

    A collection of rules compiled once and reusable across many JSON values.

    RuleSet::analyze

    fn RuleSet::analyze(self : RuleSet) -> RuleSetAnalysis

    Analyze every compiled rule and combine its data dependencies and calls.

    RuleSet::analyze_with_policy

    fn RuleSet::analyze_with_policy(self : RuleSet, policy : AnalysisPolicy) -> Result[RuleSetAnalysisGateReport, Diagnostic]

    Apply one static-analysis policy to every rule in a compiled rule set.

    RuleSet::compile

    fn RuleSet::compile(definitions : Array[RuleDefinition]) -> Result[RuleSet, Array[Diagnostic]]

    RuleSet::compile_with_limits

    fn RuleSet::compile_with_limits(definitions : Array[RuleDefinition], limits : RuleSetLimits) -> Result[RuleSet, Array[Diagnostic]]

    Compile a rule set with size, naming, and per-expression safety limits.

    RuleSet::evaluate

    fn RuleSet::evaluate(self : RuleSet, context : Json) -> RuleReport

    Evaluate every rule. Runtime errors are recorded per rule so one malformed input path does not hide the rest of the report.

    RuleSet::evaluate_batch

    fn RuleSet::evaluate_batch(self : RuleSet, contexts : Array[Json], options? : BatchOptions) -> BatchReport

    Apply one compiled rule set to a batch of independent JSON values.

    RuleSet::evaluate_with_options

    fn RuleSet::evaluate_with_options(self : RuleSet, context : Json, options : RuleEvaluationOptions) -> PolicyReport

    Evaluate rules using a configurable failure threshold.

    Informational or warning outcomes remain visible even when the selected policy treats them as advisory. Runtime errors always reject the input.

    RuleSet::from_json

    fn RuleSet::from_json(config : Json) -> Result[RuleSet, Array[Diagnostic]]

    Decode and compile a JSON array of rule definitions.

    RuleSet::from_json_with_limits

    fn RuleSet::from_json_with_limits(config : Json, limits : RuleSetLimits) -> Result[RuleSet, Array[Diagnostic]]

    Decode and compile rule definitions using explicit configuration limits.

    RuleSet::length

    fn RuleSet::length(self : RuleSet) -> Int

    RuleSet::run_test_suite

    fn RuleSet::run_test_suite(self : RuleSet, suite : RuleTestSuite) -> RuleTestSuiteReport

    Run a validated regression suite while reusing the already compiled rules.

    RuleSetAnalysis

    pub(all) struct RuleSetAnalysis {
    rule_count : Int
    total_nodes : Int
    maximum_ast_depth : Int
    estimated_cost : Int
    warning_count : Int
    note_count : Int
    called_functions : Array[String]
    referenced_paths : Array[String]
    rules : Array[RuleProgramAnalysis]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Aggregate static information for a compiled rule set.

    RuleSetAnalysis::find_rule

    fn RuleSetAnalysis::find_rule(self : RuleSetAnalysis, name : String) -> RuleProgramAnalysis?

    Look up a named rule's analysis. Rule names are compared exactly.

    RuleSetAnalysis::has_warnings

    fn RuleSetAnalysis::has_warnings(self : RuleSetAnalysis) -> Bool

    Return true when at least one rule has a warning-level finding.

    RuleSetAnalysis::references_path

    fn RuleSetAnalysis::references_path(self : RuleSetAnalysis, path : String) -> Bool

    Test whether any rule in the set references an exact normalized path.

    RuleSetAnalysis::to_json_string

    fn RuleSetAnalysis::to_json_string(self : RuleSetAnalysis, indent? : Int) -> String

    RuleSetAnalysis::uses_function

    fn RuleSetAnalysis::uses_function(self : RuleSetAnalysis, name : String) -> Bool

    Test whether any rule in the set calls the named function.

    RuleSetAnalysisGateReport

    pub(all) struct RuleSetAnalysisGateReport {
    passed : Bool
    rule_count : Int
    failed_rule_count : Int
    rules : Array[RuleAnalysisGate]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Aggregate CI gate result for a compiled rule set.

    RuleSetAnalysisGateReport::to_json_string

    fn RuleSetAnalysisGateReport::to_json_string(self : RuleSetAnalysisGateReport, indent? : Int) -> String

    RuleSetLimits

    pub(all) struct RuleSetLimits {
    max_rules : Int
    max_name_length : Int
    max_message_length : Int
    max_total_source_length : Int
    require_unique_names : Bool
    compile_limits : CompileLimits
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Defensive configuration limits for rule sets loaded from external JSON.

    RuleSetLimits::default

    fn RuleSetLimits::default() -> RuleSetLimits

    RuleTestCase

    pub(all) struct RuleTestCase {
    name : String
    input : Json
    expected_passed : Bool
    expected_failed_rules : Array[String]?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    One named regression case for a compiled rule set.

    RuleTestCase::new

    fn RuleTestCase::new(name : String, input : Json, expected_passed : Bool, expected_failed_rules? : Array[String]) -> RuleTestCase

    RuleTestCaseReport

    pub(all) struct RuleTestCaseReport {
    name : String
    matched : Bool
    expected_passed : Bool
    actual_passed : Bool
    expected_failed_rules : Array[String]?
    actual_failed_rules : Array[String]
    actual_error_rules : Array[String]
    rule_report : RuleReport
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Result of one rule regression case.

    RuleTestSuite

    pub struct RuleTestSuite {
    cases : Array[RuleTestCase]
    }

    Validated collection of rule regression cases.

    RuleTestSuite::from_json

    fn RuleTestSuite::from_json(config : Json, limits? : RuleTestSuiteLimits) -> Result[RuleTestSuite, Array[Diagnostic]]

    Decode and validate a JSON array of regression cases.

    RuleTestSuite::length

    fn RuleTestSuite::length(self : RuleTestSuite) -> Int

    RuleTestSuite::new

    RuleTestSuiteLimits

    pub(all) struct RuleTestSuiteLimits {
    max_cases : Int
    max_name_length : Int
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Defensive limits for externally supplied regression suites.

    RuleTestSuiteLimits::default

    RuleTestSuiteReport

    pub(all) struct RuleTestSuiteReport {
    passed : Bool
    case_count : Int
    matched_count : Int
    mismatched_count : Int
    cases : Array[RuleTestCaseReport]
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Aggregate result for a complete rule regression suite.

    RuleTestSuiteReport::to_json_string

    fn RuleTestSuiteReport::to_json_string(self : RuleTestSuiteReport, indent? : Int) -> String

    Severity

    pub(all) enum Severity {
    Info
    Warning
    Error
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    The importance assigned to a rule.

    Span

    pub(all) struct Span {
    start : Int
    end : Int
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    A half-open source range in a rule expression.

    Span::length

    fn Span::length(self : Span) -> Int

    Span::merge

    fn Span::merge(self : Span, other : Span) -> Span

    Span::new

    fn Span::new(start : Int, end : Int) -> Span

    TokenKind

    type TokenKind derive(Eq,
    Debug
    )

    TraceStep

    pub(all) struct TraceStep {
    span : Span
    expression : String
    value : Json
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    One observable step in expression evaluation.

    UnaryOp

    pub enum UnaryOp {
    Not
    Negate
    } derive(
    Debug
    )

    analyze

    fn analyze(program : Program) -> ProgramAnalysis

    Analyze a compiled program without executing it against user data.

    Findings are advisory: compile-time analysis never changes evaluation semantics and can therefore be introduced safely in CI and editors.

    analyze_with_policy

    fn analyze_with_policy(program : Program, policy : AnalysisPolicy) -> Result[AnalysisGateReport, Diagnostic]

    Analyze one program and decide whether it satisfies a configured CI gate.

    builtin_functions

    fn builtin_functions() -> Array[FunctionSpec]

    Return the stable catalog of functions supported by the evaluator.

    builtin_functions_json

    fn builtin_functions_json(indent? : Int) -> String

    Serialize the function catalog for documentation generators and IDEs.

    check

    fn check(source : String, context : Json) -> Result[Bool, Diagnostic]

    Compile and evaluate a rule that must produce a boolean decision.

    compile

    fn compile(source : String) -> Result[Program, Diagnostic]

    Compile a MoonRule expression into an immutable program.

    compile_with_limits

    fn compile_with_limits(source : String, limits : CompileLimits) -> Result[Program, Diagnostic]

    Compile an expression while enforcing limits suitable for untrusted input.

    evaluate

    fn evaluate(program : Program, context : Json) -> Result[Json, Diagnostic]

    Evaluate a compiled program against a JSON context.

    evaluate_with_limits

    fn evaluate_with_limits(program : Program, context : Json, limits : EvaluationLimits) -> Result[Json, Diagnostic]

    Evaluate a compiled program with an explicit execution-step budget.

    explain

    fn explain(program : Program, context : Json) -> Result[EvaluationTrace, Diagnostic]

    Evaluate a program and retain a deterministic, machine-readable trace.

    find_builtin_function

    fn find_builtin_function(name : String) -> FunctionSpec?

    Look up one built-in function by its exact rule-language name.