1use serde::Serialize;
2
3use crate::Link;
4
5#[derive(Debug, Serialize)]
7#[serde(untagged)]
8pub enum TemplateOptions {
9 Inline {
10 inline: Vec<InlineOption>,
11
12 #[serde(rename = "maxItems", skip_serializing_if = "Option::is_none")]
13 max_items: Option<u32>,
14
15 #[serde(rename = "minItems", skip_serializing_if = "Option::is_none")]
16 min_items: Option<u32>,
17
18 #[serde(rename = "selectedValues", skip_serializing_if = "Vec::is_empty")]
19 selected_values: Vec<String>,
20 },
21 Link {
22 link: Link,
23
24 #[serde(rename = "maxItems", skip_serializing_if = "Option::is_none")]
25 max_items: Option<u32>,
26
27 #[serde(rename = "minItems", skip_serializing_if = "Option::is_none")]
28 min_items: Option<u32>,
29
30 #[serde(rename = "selectedValues", skip_serializing_if = "Vec::is_empty")]
31 selected_values: Vec<String>,
32 },
33}
34
35#[derive(Debug, Serialize)]
37pub struct InlineOption {
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub prompt: Option<String>,
40
41 pub value: String,
42}
43
44impl TemplateOptions {
45 #[must_use]
46 pub fn inline<O>(options: Vec<O>) -> Self
47 where
48 O: Into<InlineOption>,
49 {
50 Self::Inline {
51 inline: options.into_iter().map(Into::into).collect(),
52 max_items: None,
53 min_items: None,
54 selected_values: vec![],
55 }
56 }
57
58 #[must_use]
59 pub fn link<L>(link: L) -> Self
60 where
61 L: Into<Link>,
62 {
63 Self::Link {
64 link: link.into(),
65 max_items: None,
66 min_items: None,
67 selected_values: vec![],
68 }
69 }
70
71 #[must_use]
72 pub fn with_max_items<V>(self, value: V) -> Self
73 where
74 V: Into<u32>,
75 {
76 match self {
77 Self::Inline {
78 inline,
79 max_items: _,
80 min_items,
81 selected_values,
82 } => Self::Inline {
83 inline,
84 max_items: Some(value.into()),
85 min_items,
86 selected_values,
87 },
88 Self::Link {
89 link,
90 max_items: _,
91 min_items,
92 selected_values,
93 } => Self::Link {
94 link,
95 max_items: Some(value.into()),
96 min_items,
97 selected_values,
98 },
99 }
100 }
101
102 #[must_use]
103 pub fn with_min_items<V>(self, value: V) -> Self
104 where
105 V: Into<u32>,
106 {
107 match self {
108 Self::Inline {
109 inline,
110 max_items,
111 min_items: _,
112 selected_values,
113 } => Self::Inline {
114 inline,
115 max_items,
116 min_items: Some(value.into()),
117 selected_values,
118 },
119 Self::Link {
120 link,
121 max_items,
122 min_items: _,
123 selected_values,
124 } => Self::Link {
125 link,
126 max_items,
127 min_items: Some(value.into()),
128 selected_values,
129 },
130 }
131 }
132
133 #[must_use]
134 pub fn with_selected_value<V>(self, value: V) -> Self
135 where
136 V: ToString,
137 {
138 match self {
139 Self::Inline {
140 inline,
141 max_items,
142 min_items,
143 mut selected_values,
144 } => {
145 selected_values.push(value.to_string());
146 Self::Inline {
147 inline,
148 max_items,
149 min_items,
150 selected_values,
151 }
152 },
153 Self::Link {
154 link,
155 max_items,
156 min_items,
157 mut selected_values,
158 } => {
159 selected_values.push(value.to_string());
160 Self::Link {
161 link,
162 max_items,
163 min_items,
164 selected_values,
165 }
166 },
167 }
168 }
169}
170
171impl InlineOption {
172 #[must_use]
173 pub fn new<V>(value: V) -> Self
174 where
175 V: ToString,
176 {
177 Self {
178 prompt: None,
179 value: value.to_string(),
180 }
181 }
182
183 #[must_use]
184 pub fn with_prompt<V>(mut self, value: V) -> Self
185 where
186 V: ToString,
187 {
188 self.prompt = Some(value.to_string());
189
190 self
191 }
192}
193
194impl<S> From<S> for InlineOption
195where
196 S: ToString,
197{
198 fn from(value: S) -> Self {
199 Self::new(value)
200 }
201}