mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
65 lines
2.6 KiB
Rust
65 lines
2.6 KiB
Rust
use crate::*;
|
|
/// Show an item only when a condition is true.
|
|
pub struct When<A>(pub bool, pub A);
|
|
impl<A> When<A> { pub fn new (c: bool, a: A) -> Self { Self(c, a) } }
|
|
/// Show one item if a condition is true and another if the condition is false
|
|
pub struct Either<A, B>(pub bool, pub A, pub B);
|
|
impl<A, B> Either<A, B> { pub fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } }
|
|
try_from_expr!(<'a, E>: When<RenderBox<'a, E>>: |state, iter| {
|
|
if let Some((Token { value: Value::Key("when"), .. }, _)) = iter.next() {
|
|
let iter = iter.clone();
|
|
let condition = iter.next();
|
|
if let Some((ref condition, _)) = condition {
|
|
let condition = state.get_bool(&condition.value).expect("no condition");
|
|
if let Some((ref content, _)) = iter.next() {
|
|
let content = state.get_content(&content.value).expect("no atom");
|
|
return Some(Self(condition, content))
|
|
}
|
|
}
|
|
}
|
|
});
|
|
try_from_expr!(<'a, E>: Either<RenderBox<'a, E>, RenderBox<'a, E>>: |state, iter| {
|
|
if let Some((Token { value: Value::Key("either"), .. }, _)) = iter.next() {
|
|
let iter = iter.clone();
|
|
let condition = iter.next();
|
|
if let Some((ref condition, _)) = condition {
|
|
let condition = state.get_bool(&condition.value).expect("no condition");
|
|
if let Some((ref content1, _)) = iter.next() {
|
|
let content1 = state.get_content(&content1.value).expect("no content1");
|
|
if let Some((ref content2, _)) = iter.next() {
|
|
let content2 = state.get_content(&content2.value).expect("no content2");
|
|
return Some(Self(condition, content1, content2))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
impl<E: Output, A: Render<E>> Content<E> for When<A> {
|
|
fn layout (&self, to: E::Area) -> E::Area {
|
|
let Self(cond, item) = self;
|
|
let mut area = E::Area::zero();
|
|
if *cond {
|
|
let item_area = item.layout(to);
|
|
area[0] = item_area.x();
|
|
area[1] = item_area.y();
|
|
area[2] = item_area.w();
|
|
area[3] = item_area.h();
|
|
}
|
|
area.into()
|
|
}
|
|
fn render (&self, to: &mut E) {
|
|
let Self(cond, item) = self;
|
|
if *cond { item.render(to) }
|
|
}
|
|
}
|
|
impl<E: Output, A: Render<E>, B: Render<E>> Content<E> for Either<A, B> {
|
|
fn layout (&self, to: E::Area) -> E::Area {
|
|
let Self(cond, a, b) = self;
|
|
if *cond { a.layout(to) } else { b.layout(to) }
|
|
}
|
|
fn render (&self, to: &mut E) {
|
|
let Self(cond, a, b) = self;
|
|
if *cond { a.render(to) } else { b.render(to) }
|
|
}
|
|
}
|
|
|