use crate::*; /// Show an item only when a condition is true. pub struct When(pub bool, pub A); impl When { /// Create a binary condition. pub const 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(pub bool, pub A, pub B); impl Either { /// Create a ternary condition. pub const fn new (c: bool, a: A, b: B) -> Self { Self(c, a, b) } } #[cfg(feature = "dsl")] try_from_expr!(<'a, E>: When>: |state, iter| { if let Some(Token { value: Value::Key("when"), .. }) = iter.peek() { let _ = iter.next().unwrap(); let condition = iter.next().expect("no condition specified"); let condition = state.get(&condition.value).expect("no condition provided"); let content = iter.next().expect("no content specified"); let content = if let Some(content) = state.get_content(&content.value) { content } else { panic!("no content corresponding to for {:?}", &content); }; return Some(Self(condition, content)) } }); #[cfg(feature = "dsl")] try_from_expr!(<'a, E>: Either, RenderBox<'a, E>>: |state, iter| { if let Some(Token { value: Value::Key("either"), .. }) = iter.peek() { let _ = iter.next().unwrap(); let condition = iter.next().expect("no condition specified"); let condition = state.get(&condition.value).expect("no condition provided"); let content = iter.next().expect("no content specified"); let content = if let Some(content) = state.get_content(&content.value) { content } else { panic!("no content 1 corresponding to {:?}", &content); }; let alternate = iter.next().expect("no alternate specified"); let alternate = if let Some(alternate) = state.get_content(&alternate.value) { alternate } else { panic!("no content 2 corresponding to {:?}", &alternate); }; return Some(Self(condition, content, alternate)) } }); impl> Content for When { 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, B: Render> Content for Either { 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) } } }