Skip to main content

banish/
lib.rs

1//! # Banish
2//! Banish is a declarative DSL for building rule-based state machines in Rust.
3//! States evaluate their rules until reaching a fixed point or triggering a transition,
4//! reducing control flow boilerplate.
5//!
6//! ## How It Works
7//! A `banish!` block contains one or more states. The machine starts at the first declared
8//! state and advances through them in declaration order. Within each state, rules are
9//! evaluated top to bottom on every pass. If any rule fires, the state loops and re-evaluates
10//! from the top. Once a full pass completes with no rules firing, the state has reached its
11//! fixed point and the machine advances to the next state.
12//!
13//! ## Syntax
14//!
15//! | Syntax | Description |
16//! |---|---|
17//! | `@name` | Declares a state. |
18//! | `rule ? condition { }` | A conditional rule. Fires when `condition` is true, then re-evaluates the state. |
19//! | `rule ? { }` | A conditionless rule. Fires exactly once on the first pass of each state entry. |
20//! | `!? { }` | Fallback branch. Runs when the preceding rule's condition is false. |
21//! | `=> @state;` | Explicit transition. Immediately jumps to another state, bypassing the scheduler. |
22//! | `return expr;` | Exits the entire `banish!` block with a value. |
23//!
24//! ## State Attributes
25//! Attributes can be placed above a state declaration to modify its behavior.
26//!
27//! | Attribute | Description |
28//! |---|---|
29//! | `isolate` | Removes the state from implicit scheduling. Only reachable via `=> @state`. |
30//! | `max_iter = N` | Caps the fixed-point loop to N iterations, then advances normally. |
31//! | `max_iter = N => @state` | Same, but transitions to `@state` on exhaustion instead of advancing. |
32//! | `max_entry = N` | Limits how many times this state can be entered. Returns on the (N+1)th entry. |
33//! | `trace` | Prints state entry and rule evaluation to stderr. Useful for debugging. |
34//!
35//! ## Example
36//! A traffic light that cycles through red, green, and yellow twice before exiting.
37//!
38//! ```rust
39//! use banish::banish;
40//!
41//! fn main() {
42//!     let mut ticks: i32 = 0;
43//!     banish! {
44//!         // Returns on the third entry immediately
45//!         #[max_entry = 2]
46//!         @red
47//!             announce ? {
48//!                 ticks = 0;
49//!                 println!("Red light");
50//!             }
51//!             timer ? ticks < 3 {
52//!                 ticks += 1;
53//!             }
54//!
55//!         @green
56//!             announce ? {
57//!                 println!("Green light");
58//!             }
59//!             timer ? ticks < 6 {
60//!                 ticks += 1;
61//!             }
62//!
63//!         @yellow
64//!             announce ? {
65//!                 println!("Yellow light");
66//!             }
67//!             timer ? ticks < 10 {
68//!                 ticks += 1;
69//!             } !? { => @red; }
70//!     }
71//! }
72//! ```
73//!
74//! ## More Examples
75//! See the [examples documentation](https://github.com/LoganFlaherty/banish/blob/main/docs/README.md)
76//! for more examples including game logic, search algorithms, and data pipelines.
77
78pub use banish_derive::banish;