Tune into the truth with Boolean Rhapsody in Dart
A module for evaluating boolean expressions using predefined functions, logical operators, and references to previously defined rules.
Highlights:
- Combine predefined boolean functions, logical operators (
and
,or
,not
), and parentheses to create complex expressions. - Supports referencing previously defined rules for modular and reusable logic.
- Ensures strict validation of syntax, variable existence, and type compatibility for robust execution.
- Functions evaluate conditions based on a dynamic context and return boolean results.
- Clear and well-defined grammar prioritizing expressiveness and error prevention.
A few examples:
Check if a required environment variable is present:
is_present(env:flag:green);
Validate that a numeric score exceeds a threshold:
number_greater_than(env:score, config:passing_score);
Compare string values for exact match:
string_equals(env:mode, config:expected_mode);
Confirm that a timestamp is before a configured deadline:
date_time_less_than(env:submission_time, config:deadline);
Ensure a minimum number of items in a list:
list_size_greater_than_equals(env:cart_items, config:min_required);
Check if a user's roles include all required permissions:
is_superset_of(env:user_roles, config:required_roles);
Instantiate function registry containing boolean functions like string_equals:
final functionRegistry = BooleanRhapsodyFunctionRegistry();
Configure analyser options with allowed prefixes, functions, and a variable validator:
final options = RhapsodyAnalyserOptions(
prefixes: ['env', 'config'],
functions: rhapsodyFunctionNames,
variableValidator: (name) => RegExp(r'^[a-zA-Z][a-zA-Z0-9]*$').hasMatch(name),
functionRegistry: functionRegistry,
);
Tokenise rule strings into a list of tokens:
final tokeniser = RhapsodyTokeniser();
final tokens = tokeniser.parse('rule example = is_present(env:flag);');
Perform semantic analysis on parsed tokens:
final analyser = RhapsodySemanticAnalyser(options);
final analysis = analyser.analyse(tokens);
Instantiate interpreter with analysed rule structure:
final interpreter = RhapsodyInterpreter(analysis);
Create evaluation context with variable bindings:
RhapsodyEvaluationContextBuilder builder =
RhapsodyEvaluationContextBuilder(prefixes: ['env', 'config']);
builder.setRefValue('env:state', 'green');
builder.setRefValue('env:alert', 'panic');
RhapsodyEvaluationContext context = builder.build();
Interpret rules against the provided evaluation context:
interpreter.interpret(context);
Print or inspect rule evaluation results:
print(context.ruleState.states);