$ show vyfor/rattles
Rattles is a minimal, dependency-free Rust library for terminal spinners and throbbers. It provides a collection of preset animations (arrows, ASCII, braille, emoji) and a flexible API for driving them via time, ticks, or frame index. The library supports both std (with a global clock via `Instant`) and no_std environments, and includes a `rattle!` macro for defining custom spinners. The architecture uses const generics for direction control (forward/reverse) and compile-time keyframe storage, enabling zero-cost abstractions. It is designed for integration with TUI frameworks like Ratatui, demonstrated by the example. The codebase is well-structured, with clean separation of concerns: `rattler` (time-based), `ticked_rattler` (stateful tick-based), and presets modules. The library has no external dependencies (except dev-dependencies for examples), and the macros generate efficient, compile-time validated spinners.
The LLM identified 4 files worth highlighting for reuse:
The `rattle!` macro generates zero-cost spinner definitions from keyframe data. It supports inline and path-based frames, 2D sizes, and produces both a struct implementing `Rattle` and a constructor function. This macro is fully self-contained and can be extracted to generate any timed animation sequence in Rust.
The `Rattler<T, REVERSED>` struct uses const generics to encode direction at compile time, eliminating runtime branching. It provides time-based frame selection via an external clock or a built-in global clock (std feature). This pattern is highly reusable for any cyclic animation or state machine where direction is known at compile time.
The `TickedRattler<T, REVERSED>` implements a stateful, tick-driven spinner. Tracks current frame index and supports manual stepping, reset, and conversion to/from `Rattler`. Implements `Iterator`, enabling integration with Rust's iterator combinators. This component is a clean example of a stateful iterator pattern for cyclic sequences.
Contains two pure functions: `apply_direction` (reverses index based on const generic bool) and `frame_at` (maps elapsed time and interval to frame index). These are minimal, dependency-free, and could be reused in any animation or scheduling system. Demonstrates efficient use of const generics for conditional logic.