Banish: A declarative framework for rule-based state machines in Rust
Compile-time generated scheduler beats manual match-loop-state hell for complex state machines.
A declarative framework for rule-based state machines in Rust.
Fixed-point rule evaluation as a procedural macro; compiles to zero-overhead Rust, not a VM.
Rust developers building layout engines, constraint solvers, game logic, or complex state machines
Datalog engines · TLA+ temporal logic · Drools rule engine
Instead of manually writing transition loops, Banish evaluates rules within a state until no rule fires (a fixed-point model), then transitions. The macro expands into regular Rust, which allows for seamless integration.
The goal is to make complex rule logic and state machines easier to express while keeping runtime costs identical to handwritten code.
The project was featured as Crate of the Week in the Rust newsletter this week. I'd love to hear your feedback.
Example: use banish::banish;
fn main() { let buffer = ["No".to_string(), "hey".to_string()]; let target = "hey".to_string(); let idx = find_index(&buffer, &target); print!("{:?}", idx) }
fn find_index(buffer: &[String], target: &str) -> Option<usize> { let mut idx = 0; banish! { @search // This must be first to prevent out-of-bounds panic below. not_found ? idx >= buffer.len() { return None; }
found ? buffer[idx] != target { idx += 1; } !? { return Some(idx); } // Rule triggered so we re-evalutate rules in search. } }
Compile-time generated scheduler beats manual match-loop-state hell for complex state machines.
TLA+ model checking without learning TLA+ — build fails if spec and code diverge.
Declarative firmware DSL in Rust with fuzz testing replacing manual linker script hell.
Compile-time model capability validation beats runtime errors every time.
Sans-I/O Raft core with pluggable transport and storage traits.
Two-commit spec repo with no working implementation or demo.