http_halforms/hal/
option.rs

1use serde::Serialize;
2
3use crate::Link;
4
5/// Representation of the options for a single template property.
6#[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/// Representation of a single option for a single template property.
36#[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}