moonrule

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

rules
validation
json
expression
policy
moon add YeeHh2004/moonrule@0.4.1
Download zip
Author
Version
0.4.1
License
Apache-2.0
Last updated
6 days ago
Downloads
12

Dependencies

README

#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

#表达式语言

类别语法
字面量truefalsenull、数字、字符串、数组
路径user.nameorders[0].totalmeta["key"]
可选访问user?.profile?.emailitems?[0]
算术+-*/%
比较==!=<<=>>=
布尔!&&||
成员value in arraykey in objectpart 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 可取 InfoWarningError。当前版本会执行全部规则并完整报告结果,不会因第一条失败而停止。

#规则回归测试

回归套件是一个 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.