Crate typed_grid

Crate typed_grid 

Source
Expand description

ยงTyped grid

Crates.io Docs.rs Build and Test License

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 version

Add 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.

Structsยง

Ctx

Traitsยง

IContext
MoveDown
MoveLeft
MoveRight
MoveUp