jdt_maybe_multiple/
lib.rs

1use anyhow::anyhow;
2use anyhow::Result;
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use serde_json::{json, Value};
5use std::fmt::{Display, Formatter};
6
7#[derive(Serialize, Deserialize, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
8#[serde(untagged)]
9pub enum MaybeMultiple<T> {
10    Single(T),
11    Multiple(Vec<T>),
12    #[default]
13    None,
14}
15
16pub struct MaybeMultipleIter<'a, T> {
17    inner: std::slice::Iter<'a, T>,
18}
19
20impl<'a, T> Iterator for MaybeMultipleIter<'a, T> {
21    type Item = &'a T;
22
23    fn next(&mut self) -> Option<Self::Item> {
24        self.inner.next()
25    }
26}
27
28impl<T: Display> Display for MaybeMultiple<T> {
29    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
30        match self {
31            MaybeMultiple::Single(value) => write!(f, "{value}"),
32            MaybeMultiple::Multiple(values) => {
33                if values.is_empty() {
34                    write!(f, "[]")
35                } else {
36                    write!(
37                        f,
38                        "[{}]",
39                        values
40                            .iter()
41                            .map(|v| v.to_string())
42                            .collect::<Vec<_>>()
43                            .join(", ")
44                    )
45                }
46            }
47            MaybeMultiple::None => write!(f, "none"),
48        }
49    }
50}
51
52impl<T> MaybeMultiple<T> {
53    pub fn iter(&'_ self) -> MaybeMultipleIter<'_, T> {
54        MaybeMultipleIter {
55            inner: self.as_ref().iter(),
56        }
57    }
58}
59
60impl<T> AsRef<[T]> for MaybeMultiple<T> {
61    fn as_ref(&self) -> &[T] {
62        match self {
63            MaybeMultiple::None => &[],
64            MaybeMultiple::Single(ref val) => std::slice::from_ref(val),
65            MaybeMultiple::Multiple(ref vals) => vals.as_slice(),
66        }
67    }
68}
69
70impl<T: PartialEq> MaybeMultiple<T> {
71    pub fn is_none(&self) -> bool {
72        *self == MaybeMultiple::None
73    }
74}
75
76impl<T> From<Option<Vec<T>>> for MaybeMultiple<T> {
77    fn from(data: Option<Vec<T>>) -> Self {
78        match data {
79            Some(x) => MaybeMultiple::Multiple(x),
80            None => MaybeMultiple::None,
81        }
82    }
83}
84
85impl<T: DeserializeOwned> From<Option<Value>> for MaybeMultiple<T> {
86    fn from(data: Option<Value>) -> Self {
87        match data {
88            Some(value) => value.into(),
89            None => MaybeMultiple::None,
90        }
91    }
92}
93
94impl<T: DeserializeOwned> From<Value> for MaybeMultiple<T> {
95    fn from(data: Value) -> Self {
96        if let Ok(vec_result) = serde_json::from_value::<Vec<T>>(data.clone()) {
97            MaybeMultiple::Multiple(vec_result)
98        } else if let Ok(single_result) = serde_json::from_value::<T>(data) {
99            MaybeMultiple::Single(single_result)
100        } else {
101            MaybeMultiple::None
102        }
103    }
104}
105
106impl<T: Serialize> From<&MaybeMultiple<T>> for Option<Value> {
107    fn from(object: &MaybeMultiple<T>) -> Self {
108        match object {
109            MaybeMultiple::None => None,
110            _ => Some(json!(object)),
111        }
112    }
113}
114
115impl<T: Serialize> From<MaybeMultiple<T>> for Option<Value> {
116    fn from(object: MaybeMultiple<T>) -> Self {
117        match object {
118            MaybeMultiple::None => None,
119            _ => Some(json!(object)),
120        }
121    }
122}
123
124impl<T: Serialize> From<&MaybeMultiple<T>> for Value {
125    fn from(object: &MaybeMultiple<T>) -> Self {
126        json!(object)
127    }
128}
129
130impl<T: Serialize> From<MaybeMultiple<T>> for Value {
131    fn from(object: MaybeMultiple<T>) -> Self {
132        json!(object)
133    }
134}
135
136impl From<String> for MaybeMultiple<String> {
137    fn from(data: String) -> Self {
138        MaybeMultiple::Single(data)
139    }
140}
141
142impl<T> From<Vec<T>> for MaybeMultiple<T> {
143    fn from(data: Vec<T>) -> Self {
144        MaybeMultiple::Multiple(data)
145    }
146}
147
148impl<T: Clone> MaybeMultiple<T> {
149    pub fn map<U, F>(self, mut f: F) -> MaybeMultiple<U>
150    where
151        F: FnMut(T) -> U,
152    {
153        match self {
154            MaybeMultiple::Multiple(vec) => {
155                MaybeMultiple::Multiple(vec.into_iter().map(f).collect())
156            }
157            MaybeMultiple::Single(val) => MaybeMultiple::Single(f(val)),
158            MaybeMultiple::None => MaybeMultiple::None,
159        }
160    }
161
162    pub fn single(&self) -> Result<T> {
163        match self {
164            MaybeMultiple::Multiple(s) => {
165                if s.len() == 1 {
166                    Ok(s[0].clone())
167                } else {
168                    Err(anyhow!("MaybeMultiple is Multiple"))
169                }
170            }
171            MaybeMultiple::Single(s) => Ok(s.clone()),
172            MaybeMultiple::None => Err(anyhow!("MaybeMultiple is None")),
173        }
174    }
175
176    pub fn multiple(&self) -> Vec<T> {
177        match self {
178            MaybeMultiple::Multiple(data) => data.clone(),
179            MaybeMultiple::Single(data) => {
180                vec![data.clone()]
181            }
182            MaybeMultiple::None => vec![],
183        }
184    }
185
186    pub fn extend(mut self, mut additional: Vec<T>) -> Self {
187        match self {
188            MaybeMultiple::Multiple(ref mut data) => {
189                data.append(&mut additional);
190                data.clone().into()
191            }
192            MaybeMultiple::Single(data) => {
193                additional.push(data.clone());
194                additional.clone().into()
195            }
196            MaybeMultiple::None => additional.clone().into(),
197        }
198    }
199
200    pub fn option(&self) -> Option<Vec<T>> {
201        match self {
202            MaybeMultiple::Multiple(v) => Some(v.clone()),
203            MaybeMultiple::Single(s) => Some(vec![s.clone()]),
204            MaybeMultiple::None => None,
205        }
206    }
207
208    /// Returns the first element, whether Single or the first of Multiple.
209    /// Returns None if this is MaybeMultiple::None or an empty Multiple.
210    pub fn first(&self) -> Option<T> {
211        match self {
212            MaybeMultiple::Single(s) => Some(s.clone()),
213            MaybeMultiple::Multiple(v) => v.first().cloned(),
214            MaybeMultiple::None => None,
215        }
216    }
217}