wowlab_common/markdown/
list.rs1use std::fmt::Display;
4
5#[derive(Clone, Copy, Debug)]
7#[non_exhaustive]
8pub enum ListStyle {
9 Dash,
10 Asterisk,
11 Bullet,
12 Ordered,
13}
14
15#[derive(Debug)]
17pub struct List {
18 items: Vec<Box<str>>,
19 style: ListStyle,
20}
21
22impl List {
23 #[must_use]
24 pub fn new() -> Self {
25 Self {
26 items: Vec::new(),
27 style: ListStyle::Dash,
28 }
29 }
30
31 #[must_use]
32 pub fn asterisk() -> Self {
33 Self {
34 items: Vec::new(),
35 style: ListStyle::Asterisk,
36 }
37 }
38
39 #[must_use]
40 pub fn bullet() -> Self {
41 Self {
42 items: Vec::new(),
43 style: ListStyle::Bullet,
44 }
45 }
46
47 #[must_use]
48 pub fn ordered() -> Self {
49 Self {
50 items: Vec::new(),
51 style: ListStyle::Ordered,
52 }
53 }
54
55 #[must_use]
56 pub fn item(mut self, text: impl Display) -> Self {
57 self.items.push(text.to_string().into_boxed_str());
58
59 self
60 }
61
62 #[must_use]
63 pub fn items<I, T>(mut self, items: I) -> Self
64 where
65 I: IntoIterator<Item = T>,
66 T: Display,
67 {
68 for item in items {
69 self.items.push(item.to_string().into_boxed_str());
70 }
71
72 self
73 }
74
75 #[must_use]
76 pub fn build(self) -> String {
77 self.items
78 .into_iter()
79 .enumerate()
80 .map(|(i, item)| match self.style {
81 ListStyle::Dash => format!("- {item}"),
82 ListStyle::Asterisk => format!("* {item}"),
83 ListStyle::Bullet => format!("• {item}"),
84 ListStyle::Ordered => format!("{}. {}", i + 1, item),
85 })
86 .collect::<Vec<_>>()
87 .join("\n")
88 }
89}
90impl Default for List {
91 fn default() -> Self {
92 Self::new()
93 }
94}