Skip to main content

verdict_rules 0.4.0 copy "verdict_rules: ^0.4.0" to clipboard
verdict_rules: ^0.4.0 copied to clipboard

A small, zero-dependency, async-native rule-evaluation engine. Compose conditions into one explainable pass/fail verdict, with real short-circuiting as a guarantee.

example/verdict_rules_example.dart

// A runnable example. pub.dev looks for `example/` and surfaces it on the
// package page, so this doubles as the first thing a reader sees.
import 'package:verdict_rules/verdict_rules.dart';

/// Builds a rule asserting that a numeric field clears a floor.
FunctionRule<Context> atLeast(String name, String field, num floor) =>
    FunctionRule(name, (Context ctx) async {
      final value = ctx[field]! as num;
      return PredicateOutcome(value >= floor, detail: '$value vs $floor');
    });

/// `eligible` below is an AndRule, so its own `detail` is always empty --
/// composing ShortCircuitEvaluator leaves no channel to build a descriptive
/// string from. `failingLeaves` is the replacement: the flattened set of
/// leaf results that actually explain a failure.
String _reason(RuleResult result) => result.failingLeaves
    .map((leaf) => leaf.detail.isEmpty
        ? leaf.ruleName
        : '${leaf.ruleName}: ${leaf.detail}')
    .join('; ');

Future<void> main() async {
  final eligible = AndRule<Context>('eligible', [
    atLeast('age_ok', 'age', 18),
    atLeast('score_ok', 'score', 60),
  ]);

  // Short-circuits: score_ok is never reached when age_ok fails.
  final tooYoung = await eligible.evaluate({'age': 16, 'score': 90});
  print('${tooYoung.passed} — ${_reason(tooYoung)}');
  print('rules actually evaluated: ${tooYoung.subResults.length}\n');

  final failedScore = await eligible.evaluate({'age': 21, 'score': 55});
  print('${failedScore.passed} — ${_reason(failedScore)}');
  print('rules actually evaluated: ${failedScore.subResults.length}\n');

  // The engine is diagnostic: it never short-circuits.
  final engine = RulesEngine<Context>([
    atLeast('age_ok', 'age', 18),
    atLeast('score_ok', 'score', 60),
  ]);
  final everything = await engine.runAll({'age': 16, 'score': 55});
  print(
    'runAll reported ${everything.results.length} rules, '
    'passed=${everything.passed}',
  );
}
0
likes
160
points
393
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A small, zero-dependency, async-native rule-evaluation engine. Compose conditions into one explainable pass/fail verdict, with real short-circuiting as a guarantee.

Repository (GitHub)
View/report issues
Contributing

Topics

#rules-engine #rule-evaluation #eligibility #decision-engine #async

License

MIT (license)

More

Packages that depend on verdict_rules