dock_crypto_utils/
extend_some.rs1#[cfg(feature = "parallel")]
2use rayon::prelude::*;
3
4#[derive(Debug, Clone, Eq, PartialEq)]
6pub struct ExtendSome<C>(pub C);
7
8impl<C: Default> Default for ExtendSome<C> {
9 fn default() -> Self {
10 Self(Default::default())
11 }
12}
13
14impl<C: IntoIterator> IntoIterator for ExtendSome<C> {
15 type Item = C::Item;
16 type IntoIter = C::IntoIter;
17
18 fn into_iter(self) -> Self::IntoIter {
19 self.0.into_iter()
20 }
21}
22
23impl<T, C: Extend<T>> Extend<Option<T>> for ExtendSome<C> {
24 fn extend<I: IntoIterator<Item = Option<T>>>(&mut self, iter: I) {
25 self.0.extend(iter.into_iter().flatten());
26 }
27}
28
29impl<T, C: Default + FromIterator<T>> FromIterator<Option<T>> for ExtendSome<C> {
30 fn from_iter<I: IntoIterator<Item = Option<T>>>(iter: I) -> Self {
31 Self(C::from_iter(iter.into_iter().flatten()))
32 }
33}
34
35#[cfg(feature = "parallel")]
36impl<T: Send, C: Default + FromParallelIterator<T> + Send> FromParallelIterator<Option<T>>
37 for ExtendSome<C>
38{
39 fn from_par_iter<I>(par_iter: I) -> Self
40 where
41 I: IntoParallelIterator<Item = Option<T>>,
42 {
43 Self(C::from_par_iter(par_iter.into_par_iter().flatten()))
44 }
45}
46
47#[cfg(feature = "parallel")]
48impl<T: Send, C: Default + ParallelExtend<T> + Send> ParallelExtend<Option<T>> for ExtendSome<C> {
49 fn par_extend<I>(&mut self, par_iter: I)
50 where
51 I: IntoParallelIterator<Item = Option<T>>,
52 {
53 self.0.par_extend(par_iter.into_par_iter().flatten());
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn basic() {
63 let ExtendSome::<Vec<_>>(arr) = [Some(1), Some(2), None, Some(4)].into_iter().collect();
64
65 assert_eq!(arr, [1, 2, 4]);
66
67 let (ExtendSome::<Vec<_>>(even), ExtendSome::<Vec<_>>(odd)) =
68 [Some(1), Some(2), None, Some(4), Some(5), None]
69 .into_iter()
70 .partition(|v| v.map_or(false, |idx| idx % 2 == 0));
71
72 assert_eq!(even, vec![2, 4]);
73 assert_eq!(odd, vec![1, 5])
74 }
75}