identity_core/common/
one_or_many.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use core::fmt::Debug;
5use core::fmt::Formatter;
6use core::hash::Hash;
7use core::mem::replace;
8use core::ops::Deref;
9use std::vec::IntoIter;
10
11use serde;
12use serde::Deserialize;
13use serde::Serialize;
14
15/// A generic container that stores exactly one or many (0+) values of a given type.
16#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
17#[serde(untagged)]
18pub enum OneOrMany<T> {
19  /// A single instance of `T`.
20  One(T),
21  /// Multiple (zero or more) instances of `T`.
22  Many(Vec<T>),
23}
24
25impl<T> OneOrMany<T> {
26  /// Returns the number of elements in the collection
27  pub fn len(&self) -> usize {
28    match self {
29      Self::One(_) => 1,
30      Self::Many(inner) => inner.len(),
31    }
32  }
33
34  /// Returns `true` if the collection is empty
35  pub fn is_empty(&self) -> bool {
36    match self {
37      Self::One(_) => false,
38      Self::Many(inner) => inner.is_empty(),
39    }
40  }
41
42  /// Returns a reference to the element at the given index.
43  pub fn get(&self, index: usize) -> Option<&T> {
44    match self {
45      Self::One(inner) if index == 0 => Some(inner),
46      Self::One(_) => None,
47      Self::Many(inner) => inner.get(index),
48    }
49  }
50
51  /// Returns a mutable reference to the element at the given index.
52  pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
53    match self {
54      Self::One(ref mut inner) if index == 0 => Some(inner),
55      Self::One(_) => None,
56      Self::Many(inner) => inner.get_mut(index),
57    }
58  }
59
60  /// Returns `true` if the collection contains the given value.
61  pub fn contains(&self, value: &T) -> bool
62  where
63    T: PartialEq<T>,
64  {
65    match self {
66      Self::One(inner) => inner == value,
67      Self::Many(inner) => inner.contains(value),
68    }
69  }
70
71  /// Adds a new value to the collection.
72  pub fn push(&mut self, value: T) {
73    match self {
74      Self::One(_) => match replace(self, Self::Many(Vec::new())) {
75        Self::One(inner) => *self = Self::Many(vec![inner, value]),
76        Self::Many(_) => unreachable!(),
77      },
78      Self::Many(ref mut inner) => {
79        if inner.is_empty() {
80          *self = Self::One(value);
81        } else {
82          inner.push(value);
83        }
84      }
85    }
86  }
87
88  /// Returns an `Iterator` that yields items from the collection.
89  pub fn iter(&self) -> impl Iterator<Item = &T> + '_ {
90    OneOrManyIter::new(self)
91  }
92
93  /// Returns a reference to the contents as a slice.
94  pub fn as_slice(&self) -> &[T] {
95    self
96  }
97
98  /// Consumes the [`OneOrMany`] and returns the contents as a [`Vec`].
99  pub fn into_vec(self) -> Vec<T> {
100    match self {
101      Self::One(inner) => vec![inner],
102      Self::Many(inner) => inner,
103    }
104  }
105}
106
107impl<T> Debug for OneOrMany<T>
108where
109  T: Debug,
110{
111  fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
112    match self {
113      Self::One(inner) => Debug::fmt(inner, f),
114      Self::Many(inner) => Debug::fmt(inner, f),
115    }
116  }
117}
118
119impl<T> Deref for OneOrMany<T> {
120  type Target = [T];
121
122  fn deref(&self) -> &Self::Target {
123    match self {
124      Self::One(inner) => core::slice::from_ref(inner),
125      Self::Many(inner) => inner,
126    }
127  }
128}
129
130impl<T> AsRef<[T]> for OneOrMany<T> {
131  fn as_ref(&self) -> &[T] {
132    self
133  }
134}
135
136impl<T> Default for OneOrMany<T> {
137  fn default() -> Self {
138    Self::Many(Vec::new())
139  }
140}
141
142impl<T> From<T> for OneOrMany<T> {
143  fn from(other: T) -> Self {
144    Self::One(other)
145  }
146}
147
148impl<T> From<Vec<T>> for OneOrMany<T> {
149  fn from(mut other: Vec<T>) -> Self {
150    if other.len() == 1 {
151      Self::One(other.pop().expect("infallible"))
152    } else {
153      Self::Many(other)
154    }
155  }
156}
157
158impl<T> From<OneOrMany<T>> for Vec<T> {
159  fn from(other: OneOrMany<T>) -> Self {
160    other.into_vec()
161  }
162}
163
164impl<T> FromIterator<T> for OneOrMany<T> {
165  fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
166    let mut iter = iter.into_iter();
167    // if the iterator contains one element or less and a correct size hint is provided we can save an allocation
168    let size_hint = iter.size_hint();
169    if size_hint.1.is_some() && (1, Some(1)) >= size_hint {
170      let mut this = iter.next().map(Self::One).unwrap_or_else(|| Self::Many(Vec::new()));
171      // if the hinted upper bound was incorrect we need to correct for it
172      for next in iter.by_ref() {
173        this.push(next);
174      }
175      this
176    } else {
177      iter.collect::<Vec<T>>().into()
178    }
179  }
180}
181
182// =============================================================================
183// Iterator
184// =============================================================================
185
186/// This struct is created by the `iter` method on [`OneOrMany`].
187struct OneOrManyIter<'a, T> {
188  inner: &'a OneOrMany<T>,
189  index: usize,
190}
191
192impl<'a, T> OneOrManyIter<'a, T> {
193  fn new(inner: &'a OneOrMany<T>) -> Self {
194    Self { inner, index: 0 }
195  }
196}
197
198impl<'a, T> Iterator for OneOrManyIter<'a, T> {
199  type Item = &'a T;
200
201  fn next(&mut self) -> Option<Self::Item> {
202    self.index += 1;
203    self.inner.get(self.index - 1)
204  }
205}
206
207// =============================================================================
208// IntoIterator
209// =============================================================================
210
211enum Either<L, R> {
212  Left(L),
213  Right(R),
214}
215
216/// This struct is created by the `into_iter` method on [`OneOrMany`]
217/// (provided by the [IntoIterator](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html) trait).
218pub struct OneOrManyIntoIterator<T> {
219  iter: Either<Option<T>, IntoIter<T>>,
220}
221
222impl<T> OneOrManyIntoIterator<T> {
223  fn new(inner: OneOrMany<T>) -> Self {
224    let iter = match inner {
225      OneOrMany::One(item) => Either::Left(Some(item)),
226      OneOrMany::Many(vec) => Either::Right(vec.into_iter()),
227    };
228
229    Self { iter }
230  }
231}
232
233impl<T> Iterator for OneOrManyIntoIterator<T> {
234  type Item = T;
235
236  fn next(&mut self) -> Option<Self::Item> {
237    match self.iter {
238      Either::Left(ref mut item_opt) => item_opt.take(),
239      Either::Right(ref mut iter) => iter.next(),
240    }
241  }
242}
243
244impl<T> IntoIterator for OneOrMany<T> {
245  type Item = T;
246
247  type IntoIter = OneOrManyIntoIterator<T>;
248
249  fn into_iter(self) -> Self::IntoIter {
250    OneOrManyIntoIterator::new(self)
251  }
252}
253
254#[cfg(test)]
255mod tests {
256  use super::*;
257
258  #[test]
259  fn from_iterator_empty() {
260    let empty_vec = Vec::<u32>::new();
261    assert_eq!(OneOrMany::from_iter(empty_vec.clone()), OneOrMany::Many(empty_vec));
262  }
263
264  #[test]
265  fn from_iterator_single() {
266    let single_item = [1];
267    assert_eq!(OneOrMany::from_iter(single_item), OneOrMany::One(1));
268  }
269
270  #[test]
271  fn from_iterator_many() {
272    let letters = ["a", "b", "c", "d"];
273    assert_eq!(OneOrMany::from_iter(letters), OneOrMany::Many(vec!["a", "b", "c", "d"]));
274  }
275
276  #[test]
277  fn from_iterator_iter() {
278    let none = OneOrMany::Many(Vec::<u32>::new());
279    assert_eq!(OneOrMany::from_iter(none.iter()), OneOrMany::Many(Vec::<&u32>::new()));
280
281    let one = OneOrMany::One(42);
282    assert_eq!(OneOrMany::from_iter(one.iter()), OneOrMany::One(&42));
283
284    let two = OneOrMany::Many(vec![0, 1]);
285    assert_eq!(OneOrMany::from_iter(two.iter()), OneOrMany::Many(vec![&0, &1]));
286  }
287
288  #[test]
289  fn push_from_zero_elements() {
290    let mut collection = OneOrMany::Many(Vec::<u32>::new());
291    collection.push(42);
292    assert_eq!(collection, OneOrMany::One(42));
293  }
294
295  #[test]
296  fn push_one_element() {
297    let mut collection = OneOrMany::One(42);
298    collection.push(42);
299    assert_eq!(collection, OneOrMany::Many(vec![42, 42]));
300  }
301
302  #[test]
303  fn push_many_elements() {
304    let v: Vec<i32> = (0..42).collect();
305    let mut collection = OneOrMany::Many(v);
306    collection.push(42);
307    assert_eq!(collection, OneOrMany::Many((0..=42).collect()));
308  }
309
310  #[test]
311  fn test_iter() {
312    let one_or_many = OneOrMany::Many(Vec::<u32>::new());
313    assert!(one_or_many.iter().next().is_none());
314
315    let one_or_many = OneOrMany::One(1u32);
316    assert_eq!(one_or_many.iter().next().unwrap(), &1);
317
318    let one_or_many = OneOrMany::Many(vec![42u32]);
319    let mut iter = one_or_many.iter();
320    assert_eq!(iter.next().unwrap(), &42);
321    assert!(iter.next().is_none());
322
323    let one_or_many = OneOrMany::Many(vec![42u32, 1337u32]);
324    let mut iter = one_or_many.iter();
325    assert_eq!(iter.next().unwrap(), &42);
326    assert_eq!(iter.next().unwrap(), &1337);
327    assert!(iter.next().is_none());
328  }
329
330  #[test]
331  fn test_into_iter() {
332    let one_or_many = OneOrMany::Many(Vec::<u32>::new());
333    assert!(one_or_many.into_iter().next().is_none());
334
335    let one_or_many = OneOrMany::One(1u32);
336    assert_eq!(one_or_many.into_iter().next().unwrap(), 1);
337
338    let one_or_many = OneOrMany::Many(vec![42u32]);
339    let mut into_iter = one_or_many.into_iter();
340    assert_eq!(into_iter.next().unwrap(), 42);
341    assert!(into_iter.next().is_none());
342
343    let one_or_many = OneOrMany::Many(vec![42u32, 1337u32]);
344    let mut into_iter = one_or_many.into_iter();
345    assert_eq!(into_iter.next().unwrap(), 42);
346    assert_eq!(into_iter.next().unwrap(), 1337);
347    assert!(into_iter.next().is_none());
348  }
349}