aws_iam/model/
containers.rs

1/*!
2Provides some basic container enums that are used by the Policy model.
3*/
4
5use serde::{Deserialize, Serialize};
6use std::cmp::Ordering;
7use std::hash::{Hash, Hasher};
8use std::iter::FromIterator;
9
10// ------------------------------------------------------------------------------------------------
11// Public Types
12// ------------------------------------------------------------------------------------------------
13
14///
15/// A container used by a number of elements where the JSON serialization may be  a single
16/// string,  or an array of string values.
17///
18#[derive(Debug, Serialize, Deserialize)]
19#[serde(untagged)]
20pub enum OneOrAll<T = String> {
21    /// A single statement.
22    One(T),
23    /// A vector of statements.
24    All(Vec<T>),
25}
26
27///
28/// A container used by a number of elements where the JSON serialization may be a wild-card
29/// value, a single string,  or an array of string values.
30///
31#[derive(Debug, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum OneOrAny<T = String> {
34    /// The wildcard value, may be Any or All depending on use.
35    #[serde(rename = "*")]
36    Any,
37    /// One element of type `T`
38    One(T),
39    /// A JSON array with elements of type `T`.
40    AnyOf(Vec<T>),
41}
42
43// ------------------------------------------------------------------------------------------------
44// Implementations
45// ------------------------------------------------------------------------------------------------
46
47impl<T> From<T> for OneOrAll<T> {
48    fn from(v: T) -> Self {
49        Self::One(v)
50    }
51}
52
53impl<T> From<Vec<T>> for OneOrAll<T> {
54    fn from(vs: Vec<T>) -> Self {
55        Self::All(vs)
56    }
57}
58
59impl<T> FromIterator<T> for OneOrAll<T> {
60    #[inline]
61    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> OneOrAll<T> {
62        Self::All(Vec::from_iter(iter.into_iter()))
63    }
64}
65
66impl<T: Clone> Clone for OneOrAll<T> {
67    #[inline]
68    fn clone(&self) -> Self {
69        match self {
70            Self::One(v) => Self::One(v.clone()),
71            Self::All(vs) => Self::All(vs.clone()),
72        }
73    }
74}
75
76impl<T: PartialEq> PartialEq for OneOrAll<T> {
77    #[inline]
78    fn eq(&self, other: &Self) -> bool {
79        match (self, other) {
80            (Self::One(lhs), Self::One(rhs)) => lhs.eq(rhs),
81            (Self::All(lhs), Self::All(rhs)) => lhs.eq(rhs),
82            _ => false,
83        }
84    }
85}
86
87impl<T: Eq> Eq for OneOrAll<T> {}
88
89impl<T: PartialOrd> PartialOrd for OneOrAll<T> {
90    #[inline]
91    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
92        match (self, other) {
93            (Self::One(lhs), Self::One(rhs)) => lhs.partial_cmp(rhs),
94            (Self::All(lhs), Self::All(rhs)) => lhs.partial_cmp(rhs),
95            (Self::One(lhs), Self::All(rhs)) => {
96                vec![lhs].partial_cmp(&rhs.iter().collect::<Vec<&T>>())
97            }
98            (Self::All(lhs), Self::One(rhs)) => {
99                lhs.iter().collect::<Vec<&T>>().partial_cmp(&vec![rhs])
100            }
101        }
102    }
103}
104
105impl<T: Ord> Ord for OneOrAll<T> {
106    fn cmp(&self, other: &Self) -> Ordering {
107        match (self, other) {
108            (Self::One(lhs), Self::One(rhs)) => lhs.cmp(rhs),
109            (Self::All(lhs), Self::All(rhs)) => lhs.cmp(rhs),
110            (Self::One(lhs), Self::All(rhs)) => vec![lhs].cmp(&rhs.iter().collect::<Vec<&T>>()),
111            (Self::All(lhs), Self::One(rhs)) => lhs.iter().collect::<Vec<&T>>().cmp(&vec![rhs]),
112        }
113    }
114}
115
116impl<T: Hash> Hash for OneOrAll<T> {
117    #[inline]
118    fn hash<H: Hasher>(&self, state: &mut H) {
119        match self {
120            Self::One(v) => Hash::hash(v, state),
121            Self::All(vs) => Hash::hash(vs, state),
122        }
123    }
124}
125
126impl<T> OneOrAll<T> {
127    ///
128    /// Returns `true` if the option is an `One` value.
129    ///
130    pub fn is_one(&self) -> bool {
131        matches!(self, OneOrAll::One(_))
132    }
133
134    ///
135    /// Returns `true` if the option is an `All` value.
136    ///
137    pub fn is_all(&self) -> bool {
138        matches!(self, OneOrAll::All(_))
139    }
140
141    ///
142    /// Converts from OneOrAll<T> to Option<T>.
143    ///
144    /// Converts `self` into an `Option<T>`, consuming `self`, and discarding `All` values.
145    ///
146    pub fn one(self) -> Option<T> {
147        match self {
148            OneOrAll::One(value) => Some(value),
149            _ => None,
150        }
151    }
152
153    ///
154    /// Converts from OneOrAll<T> to Option<T>.
155    ///
156    /// Converts `self` into an `Option<T>`, consuming `self`, and `One` values.
157    ///
158    pub fn all(self) -> Option<Vec<T>> {
159        match self {
160            OneOrAll::All(values) => Some(values),
161            _ => None,
162        }
163    }
164}
165
166// ------------------------------------------------------------------------------------------------
167
168impl<T> From<T> for OneOrAny<T> {
169    fn from(v: T) -> Self {
170        Self::One(v)
171    }
172}
173
174impl<T> From<Vec<T>> for OneOrAny<T> {
175    fn from(vs: Vec<T>) -> Self {
176        Self::AnyOf(vs)
177    }
178}
179
180impl<T> FromIterator<T> for OneOrAny<T> {
181    #[inline]
182    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> OneOrAny<T> {
183        Self::AnyOf(Vec::from_iter(iter.into_iter()))
184    }
185}
186
187impl<T: Clone> Clone for OneOrAny<T> {
188    #[inline]
189    fn clone(&self) -> Self {
190        match self {
191            Self::Any => self.clone(),
192            Self::One(v) => Self::One(v.clone()),
193            Self::AnyOf(vs) => Self::AnyOf(vs.clone()),
194        }
195    }
196}
197
198impl<T: PartialEq> PartialEq for OneOrAny<T> {
199    #[inline]
200    fn eq(&self, other: &Self) -> bool {
201        match (self, other) {
202            (Self::Any, Self::Any) => true,
203            (Self::One(lhs), Self::One(rhs)) => lhs.eq(rhs),
204            (Self::AnyOf(lhs), Self::AnyOf(rhs)) => lhs.eq(rhs),
205            _ => false,
206        }
207    }
208}
209
210impl<T: Eq> Eq for OneOrAny<T> {}
211
212//
213// **Note**: There is no implementation of PartialOrd or Ord here as it's
214// really not clear how you would order the value `Any` against the inner
215// type.
216//
217
218impl<T: Hash> Hash for OneOrAny<T> {
219    #[inline]
220    fn hash<H: Hasher>(&self, state: &mut H) {
221        match self {
222            Self::Any => Hash::hash(self, state),
223            Self::One(v) => Hash::hash(v, state),
224            Self::AnyOf(vs) => Hash::hash(vs, state),
225        }
226    }
227}
228
229impl<T> OneOrAny<T> {
230    ///
231    /// Returns `true` if the option is an `Any` value.
232    ///
233    pub fn is_any(&self) -> bool {
234        matches!(self, OneOrAny::Any)
235    }
236
237    ///
238    /// Returns `true` if the option is an `One` value.
239    ///
240    pub fn is_one(&self) -> bool {
241        matches!(self, OneOrAny::One(_))
242    }
243
244    ///
245    /// Returns `true` if the option is an `AnyOf` value.
246    ///
247    pub fn is_any_of(&self) -> bool {
248        matches!(self, OneOrAny::AnyOf(_))
249    }
250
251    ///
252    /// Converts from OneOrAny<T> to Option<T>.
253    ///
254    /// Converts `self` into an `Option<T>`, consuming `self`, and discarding either `Any` or
255    /// `AnyOf` values.
256    ///
257    pub fn one(self) -> Option<T> {
258        match self {
259            OneOrAny::One(value) => Some(value),
260            _ => None,
261        }
262    }
263
264    ///
265    /// Converts from OneOrAny<T> to Option<T>.
266    ///
267    /// Converts `self` into an `Option<T>`, consuming `self`, and discarding either `Any` or
268    /// `One` values.
269    ///
270    pub fn any_of(self) -> Option<Vec<T>> {
271        match self {
272            OneOrAny::AnyOf(values) => Some(values),
273            _ => None,
274        }
275    }
276}
277
278// ------------------------------------------------------------------------------------------------
279// Unit Tests
280// ------------------------------------------------------------------------------------------------
281
282#[cfg(test)]
283mod tests {
284    use super::*;
285
286    #[test]
287    fn test_one_or_all_from_one() {
288        let v: OneOrAll<i32> = OneOrAll::from(10);
289        assert!(v.is_one());
290        assert_eq!(v.one(), Some(10));
291    }
292
293    #[test]
294    fn test_one_or_all_from_all() {
295        let v: OneOrAll<i32> = OneOrAll::from(vec![10, 9, 8]);
296        assert!(v.is_all());
297        assert_eq!(v.all(), Some(vec![10, 9, 8]));
298    }
299
300    #[test]
301    fn test_one_or_all_se_one() {
302        let v: OneOrAll<i32> = OneOrAll::from(10);
303        let s = serde_json::to_string(&v).expect("Could not serialize");
304        assert_eq!(s, "10");
305    }
306
307    #[test]
308    fn test_one_or_all_se_all() {
309        let v: OneOrAll<i32> = OneOrAll::from(vec![10, 9, 8]);
310        let s = serde_json::to_string(&v).expect("Could not serialize");
311        assert_eq!(s, "[10,9,8]");
312    }
313
314    // --------------------------------------------------------------------------------------------
315
316    #[test]
317    fn test_one_or_any_any() {
318        let v: OneOrAny<i32> = OneOrAny::Any;
319        assert!(v.is_any());
320    }
321
322    #[test]
323    fn test_one_or_any_from_one() {
324        let v: OneOrAny<i32> = OneOrAny::from(10);
325        assert!(v.is_one());
326        assert_eq!(v.one(), Some(10));
327    }
328
329    #[test]
330    fn test_one_or_any_from_all() {
331        let v: OneOrAny<i32> = OneOrAny::from(vec![10, 9, 8]);
332        assert!(v.is_any_of());
333        assert_eq!(v.any_of(), Some(vec![10, 9, 8]));
334    }
335
336    #[test]
337    #[ignore]
338    fn test_one_or_any_se_any() {
339        let v: OneOrAny<i32> = OneOrAny::Any;
340        let s = serde_json::to_string(&v).expect("Could not serialize");
341        assert_eq!(s, "*");
342    }
343
344    #[test]
345    fn test_one_or_any_se_one() {
346        let v: OneOrAny<i32> = OneOrAny::from(10);
347        let s = serde_json::to_string(&v).expect("Could not serialize");
348        assert_eq!(s, "10");
349    }
350
351    #[test]
352    fn test_one_or_any_se_all() {
353        let v: OneOrAny<i32> = OneOrAny::from(vec![10, 9, 8]);
354        let s = serde_json::to_string(&v).expect("Could not serialize");
355        assert_eq!(s, "[10,9,8]");
356    }
357}