Skip to main content

orx_parallel/infallible/
xap.rs

1use crate::infallible::fun::Map;
2use crate::sizes::Size;
3use crate::sizes::{Bin, One};
4
5/// Transformation from one input to zero, one, or many output values.
6pub trait Xap: Copy + Send {
7    /// Input item type.
8    type I;
9
10    /// Output item type.
11    type O;
12
13    /// Output cardinality marker.
14    type Size: Size;
15
16    /// Iterator-like container of output values.
17    type Values: IntoIterator<Item = Self::O>;
18
19    /// Applies the transformation to one input value.
20    fn xap(&self, i: Self::I) -> Self::Values;
21
22    // transformations
23
24    /// Maps each output value.
25    fn map<Q, H>(self, h: H) -> MapOf<Self, Q, H>
26    where
27        H: Fn(Self::O) -> Q + Copy + Send,
28    {
29        <Self::Size as Size>::map(self, h)
30    }
31
32    /// Inspects each output value.
33    fn inspect<H>(self, h: H) -> InsOf<Self, H>
34    where
35        H: Fn(&Self::O) + Copy + Send,
36    {
37        <Self::Size as Size>::inspect(self, h)
38    }
39
40    /// Filters output values.
41    fn filter<H>(self, h: H) -> FilOf<Self, H>
42    where
43        H: Fn(&Self::O) -> bool + Copy + Send,
44    {
45        <Self::Size as Size>::filter(self, h)
46    }
47
48    /// Maps and optionally filters output values.
49    fn filter_map<Q, H>(self, h: H) -> FilMapOf<Self, Q, H>
50    where
51        H: Fn(Self::O) -> Option<Q> + Copy + Send,
52    {
53        <Self::Size as Size>::filter_map(self, h)
54    }
55
56    /// Expands each output value into more values.
57    fn flat_map<V, H>(self, h: H) -> FlatMapOf<Self, V, H>
58    where
59        V: IntoIterator,
60        H: Fn(Self::O) -> V + Copy + Send,
61    {
62        <Self::Size as Size>::flat_map(self, h)
63    }
64
65    /// Flattens nested output values.
66    fn flatten(self) -> FlattenOf<Self>
67    where
68        Self::O: IntoIterator,
69    {
70        <Self::Size as Size>::flatten(self)
71    }
72
73    // transformations - helper
74
75    /// Applies a map implementation object to each output value.
76    fn mapped<M>(self, m: M) -> MappedOf<Self, M>
77    where
78        M: Map<I = Self::O>,
79    {
80        <Self::Size as Size>::mapped(self, m)
81    }
82}
83
84// one
85
86/// Convenience methods for xaps that always yield exactly one value.
87pub trait XapOne: Xap<Size = One> {
88    #[inline(always)]
89    /// Returns the single output value.
90    fn one_value(&self, i: Self::I) -> Self::O {
91        // SAFETY: by definition the result has exactly one element
92        unsafe { self.xap(i).into_iter().next().unwrap_unchecked() }
93    }
94}
95
96impl<X: Xap<Size = One>> XapOne for X {}
97
98// bin
99
100/// Convenience methods for xaps that yield zero or one value.
101pub trait XapBin: Xap<Size = Bin> {
102    #[inline(always)]
103    /// Returns the optional output value.
104    fn bin_value(&self, i: Self::I) -> Option<Self::O> {
105        // SAFETY: by definition the result has exactly zero or one element
106        self.xap(i).into_iter().next()
107    }
108}
109
110impl<X: Xap<Size = Bin>> XapBin for X {}
111
112// helper types
113
114/// Resulting xap type after `map`.
115pub type MapOf<X, Q, H> = <<X as Xap>::Size as Size>::Map<X, Q, H>;
116
117/// Resulting xap type after `inspect`.
118pub type InsOf<X, H> = <<X as Xap>::Size as Size>::Inspect<X, H>;
119
120/// Resulting xap type after `filter`.
121pub type FilOf<X, H> = <<X as Xap>::Size as Size>::Filter<X, H>;
122
123/// Resulting xap type after `filter_map`.
124pub type FilMapOf<X, Q, H> = <<X as Xap>::Size as Size>::FilterMap<X, Q, H>;
125
126/// Resulting xap type after `flat_map`.
127pub type FlatMapOf<X, V, H> = <<X as Xap>::Size as Size>::FlatMap<X, V, H>;
128
129/// Resulting xap type after `flatten`.
130pub type FlattenOf<X> = <<X as Xap>::Size as Size>::Flatten<X>;
131
132/// Resulting xap type after `mapped`.
133pub type MappedOf<X, M> = <<X as Xap>::Size as Size>::Mapped<X, M>;