tengri/src/draw/thunk.rs
2026-07-10 18:24:44 +03:00

48 lines
1.3 KiB
Rust

use crate::*;
/// Because we can't implement [Draw] for `F: FnOnce...` without conflicts.
pub struct Thunk<T: Screen, F>(pub F, std::marker::PhantomData<T>);
impl<T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> Draw<T> for Thunk<T, F> {
fn draw (self, to: &mut T) -> Perhaps<XYWH<T::Unit>> {
(self.0)(to)
}
}
/// Basic [Draw]able closure.
///
/// ```
/// # use tengri::*;
/// # fn test () -> impl Draw<Tui> {
/// thunk(|to: &mut Tui|Ok(Some(to.1)))
/// # }
/// ```
pub const fn thunk <T: Screen, F: FnOnce(&mut T)->Perhaps<XYWH<T::Unit>>> (
draw: F
) -> Thunk<T, F> {
Thunk(draw, std::marker::PhantomData)
}
/// Only render when condition is true.
///
/// ```
/// # use tengri::*;
/// # fn test () -> impl Draw<Tui> {
/// when(true, "Yes")
/// # }
/// ```
pub const fn when <T: Screen> (condition: bool, draw: impl Draw<T>) -> impl Draw<T> {
thunk(move|to: &mut T|if condition { draw.draw(to) } else { Ok(Default::default()) })
}
/// Render one thing if a condition is true and another false.
///
/// ```
/// # use tengri::*;
/// # fn test () -> impl Draw<Tui> {
/// either(true, "Yes", "No")
/// # }
/// ```
pub const fn either <T: Screen> (condition: bool, a: impl Draw<T>, b: impl Draw<T>) -> impl Draw<T> {
thunk(move|to: &mut T|if condition { a.draw(to) } else { b.draw(to) })
}