jdt_maybe_multiple/
lib.rs1use 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 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}