1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Animated status lines for terminal UIs, paced by the host's work.
//!
//! A [`Shimmer`] is one running animation, made from a [`Recipe`] of [`stock::ROSTER`]. It dresses
//! a caption, such as "Working", and paints the status line's lead (a mark of glyphs, the
//! caption's letters, and a tail of cells after them) over a backdrop of background colors. It
//! also paints the bullet in front of a running sub-task, such as a tool call.
//!
//! The host drives a shimmer with commands, each holding until the next replaces it:
//! [`Shimmer::show`] sets the caption, [`Shimmer::set_spell`] what the host is doing, and
//! [`Shimmer::set_intensity`] how hard it works. Each frame, the host passes the time elapsed since
//! the previous frame to [`Shimmer::advance`], which runs whole ticks of [`TICK`], and draws the
//! [`Row`] that [`Shimmer::status`] paints. Paint depends only on the recipe, the seed, the
//! commands so far, the [`Palette`], and the [`Motion`]: libshimmer reads no clock or environment
//! and keeps no global state.
//!
//! A host that learns of work in lumps can smooth them with a [`Reservoir`], and a picker can
//! preview a recipe by playing the [`script`]. The companion crate libshimmer-ratatui converts a
//! row into ratatui spans and lays its backdrop into a ratatui buffer.
//!
//! ```
//! use std::time::Duration;
//!
//! use libshimmer::{Glyphs, Intensity, Motion, Palette, Rgb, Shimmer, Spell, stock};
//!
//! let recipe = stock::named("Lava Lamp").expect("a stock recipe");
//! let mut shimmer = Shimmer::new(recipe, 7, Glyphs::BASE)?;
//! shimmer.set_spell(Spell::Busy);
//! shimmer.show("Compiling");
//! shimmer.set_intensity(Intensity::new(0.6));
//! shimmer.advance(Duration::from_millis(100));
//! let palette = Palette { fg: Rgb::new(208, 208, 208), bg: Rgb::new(21, 21, 21) };
//! let row = shimmer.status(palette, Motion { mark: true, letters: true });
//! let lead: String = row.cells().map(|(symbol, _)| symbol).collect();
//! assert_eq!(lead, "● Compiling");
//! # Ok::<(), libshimmer::Unfit>(())
//! ```
use Duration;
pub use ;
pub use ;
pub use Reservoir;
pub use ;
/// One tick of shimmer time; a host that draws every tick schedules frames this far apart.
pub const TICK: Duration = from_millis;
/// A gap between frames longer than this advances a shimmer by one tick, as after a pause in drawing.
pub const STALE: Duration = from_secs;
// P13: a host may keep a shimmer on any thread.
const _: = ;