use crate::ui::UIWidget; use maud::{Markup, Render, html}; #[allow(non_snake_case)] #[must_use] pub fn OrderedList() -> ListWidget { ListWidget(Vec::new(), true) } #[allow(non_snake_case)] #[must_use] pub fn UnorderedList() -> ListWidget { ListWidget(Vec::new(), false) } pub struct ListWidget(Vec>, bool); impl ListWidget { #[must_use] pub fn push(mut self, element: T) -> Self { self.0.push(Box::new(element)); self } #[must_use] pub fn push_some T>( mut self, option: Option, then: U, ) -> Self { if let Some(val) = option { self.0.push(Box::new(then(val))); } self } #[must_use] pub fn push_if T>( mut self, condition: bool, then: U, ) -> Self { if condition { self.0.push(Box::new(then())); } self } #[must_use] pub fn push_for_each(mut self, items: &[X], mut action: F) -> Self where T: UIWidget + 'static, F: FnMut(&X) -> T, { for item in items { self.0.push(Box::new(action(item))); } self } } impl Render for ListWidget { fn render(&self) -> Markup { self.render_with_class("") } } impl UIWidget for ListWidget { fn can_inherit(&self) -> bool { true } fn base_class(&self) -> Vec { vec![] } fn extended_class(&self) -> Vec { vec![] } fn render_with_class(&self, class: &str) -> Markup { let inner = html! { @for e in &self.0 { li { (e.as_ref()) }; } }; if self.1 { html! { ol class=(class) { (inner); } } } else { html! { ul class=(class) { (inner); } } } } }