Expand description
ยงTyped grid
Strongly typed grid navigation in Rust with compile-time movement constraints.
typed_grid is a Rust procedural macro crate that generates a grid of position types (PosXxY) and enforces legal movements (left, right, up, down) at compile time using Rustโs type system. Inspired by dependently typed programming, it encodes position and movement rules in the type system itselfโensuring that only valid transitions are representable and catchable by the compiler.
This is especially useful in domains such as:
- Grid-based games
- UI navigation
- Embedded systems
- Robotics path planning
- Finite state machines over 2D layouts
ยงโจ Features
- โ Compile-time checked movement logic
- โ Zero runtime cost for boundary enforcement
- โ Custom per-position logic via trait implementations
- โ Composable movement sequences
- โ Custom state tracking across movements
ยง๐ฆ Installation
Add this to your Cargo.toml:
[dependencies]
typed_grid = "*" # or replace with latest versionAdd the macro import to your crate root:
use typed_grid::*;ยงโ๏ธ Usage
use typed_grid::*;
typed_grid!(2, 2); // Generates a 2x2 grid
impl Moved for i32 {
fn moved(&mut self, p: Position) {
*self += 1;
println!("MOVED: {p:?} {self}")
}
}
fn run(start: Ctx<Pos0x0, i32>) -> Ctx<Pos0x0, i32> {
start.right().up().down().left()
}
let pos = Ctx(Pos0x0, 42);
let pos = pos.right().up().down().left();
let pos = run(pos);ยง๐ง Concepts
ยงtyped_grid!(W, H)
This macro generates:
- Position types like
Pos0x0,Pos1x2, etc. - A
Ctx<P, T>wrapper for combining a position and your custom state - Movement trait implementations (
MoveRight,MoveLeft,MoveUp,MoveDown) encoded at the type level
ยงtyped_grid_ext!(W, H)
The typed_grid_ext! macro generates movements with traits (IPosXxY<T>) allowing for more composable and generic movement logic.
typed_grid_ext!(2, 5);
fn moves<P: IPos0x0<T>, T: Moved + Debug>(start: P) -> impl IPos0x1<T> {
start.right().up().up().up().up().down().down().left().down()
}ยงCtx<P, T>
Ctx is a context object wrapping a position P and user-defined state T.
You move across the grid using:
ctx.right().up().down().left();ยงMoved Trait
You MUST implement the Moved trait (generated by macro) for your custom state type (T) to receive notifications whenever a movement occurs.
trait Moved {
fn moved(&mut self, to: Position);
}This allows mutation or side-effects during position transitions.
ยง๐ Compile-time Safety
Invalid moves are caught at compile time:
typed_grid!(2, 2);
let pos = Ctx(Pos1x1, ());
let new_pos = pos.right(); // โ Compile-time error: Pos2x1 doesn't existยง๐ Why?
Rather than relying on runtime conditionals or grid bounds checks, typed_grid ensures safety using Rustโs type system. You cannot move to an invalid position, and legal transitions are encoded via trait bounds.
ยง๐งช Testing
To run tests:
cargo test --workspaceยง๐ Explore the samples
Examples of macro expansion and usage are available under samples/src.
To run examples:
cargo run -p samplesยง๐ Release
This crate uses cargo-release for publishing and version management.
To tag and publish a new release:
cargo release {major|minor|patch}ยง๐ฎ Wishlist
- Optional position metadata
- Visual debugger or macro-generated grid visualization
- Support for 3D or N-dimensional grids
ยง๐ฌ Contributing
Contributions are welcome! Please open issues for bugs, ideas, or improvements.
ยง๐ License
ยง๐ Acknowledgements
Inspired by dependently typed languages, denotational design, and a love for statically enforced correctness.
Macrosยง
- typed_
grid - Generates types for grid navigation.
- typed_
grid_ ext - Generates types for grid navigation with extension methods.