exclusive_choice/
derivatives.rs

1//! Derivative Choice types from helper methods.
2use super::*;
3
4#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
5pub struct LeftFilterIter<I, A, B> {
6    pub(super) iter: I,
7    pub(super) _l: std::marker::PhantomData<A>,
8    pub(super) _r: std::marker::PhantomData<B>,
9}
10
11impl<I: Iterator<Item = Either<A, B>>, A, B> Iterator for LeftFilterIter<I, A, B> {
12    type Item = A;
13
14    fn next(&mut self) -> Option<A> {
15        loop {
16            match self.iter.next() {
17                Some(Either::Left(a)) => break Some(a),
18                Some(Either::Right(_)) => continue,
19                None => break None,
20            }
21        }
22    }
23}
24
25#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
26pub struct RightFilterIter<I, A, B> {
27    pub(super) iter: I,
28    pub(super) _l: std::marker::PhantomData<A>,
29    pub(super) _r: std::marker::PhantomData<B>,
30}
31
32impl<I: Iterator<Item = Either<A, B>>, A, B> Iterator for RightFilterIter<I, A, B> {
33    type Item = B;
34
35    fn next(&mut self) -> Option<B> {
36        loop {
37            match self.iter.next() {
38                Some(Either::Left(_)) => continue,
39                Some(Either::Right(b)) => break Some(b),
40                None => break None,
41            }
42        }
43    }
44}
45
46#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
47pub struct Swap<T> {
48    pub(super) choice: T,
49}
50
51impl<T: Choice> DynChoice for Swap<T> {
52    type Left = T::Right;
53    type Right = T::Left;
54
55    fn into_left(self: Box<Self>) -> T::Right {
56        self.choice.right()
57    }
58
59    fn into_right(self: Box<Self>) -> T::Left {
60        self.choice.left()
61    }
62}
63
64#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
65pub struct ChooseMap<T, U> {
66    pub(super) choice: T,
67    pub(super) other: U,
68}
69
70impl<T: Choice, U: Choice, C, D> DynChoice for ChooseMap<T, U>
71where
72    U::Left: FnOnce(T::Left) -> C,
73    U::Right: FnOnce(T::Right) -> D,
74{
75    type Left = C;
76    type Right = D;
77
78    fn into_left(self: Box<Self>) -> C {
79        (self.other.left())(self.choice.left())
80    }
81
82    fn into_right(self: Box<Self>) -> D {
83        (self.other.right())(self.choice.right())
84    }
85}
86
87#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
88pub struct LeftCoBind<T, F> {
89    pub(super) choice: T,
90    pub(super) cobind: F,
91}
92
93impl<T: Choice, C, F: FnOnce(T) -> C> DynChoice for LeftCoBind<T, F> {
94    type Left = C;
95    type Right = T::Right;
96
97    fn into_left(self: Box<Self>) -> C {
98        (self.cobind)(self.choice)
99    }
100
101    fn into_right(self: Box<Self>) -> T::Right {
102        self.choice.right()
103    }
104}
105
106#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
107pub struct RightCoBind<T, F> {
108    pub(super) choice: T,
109    pub(super) cobind: F,
110}
111
112impl<T: Choice, C, F: FnOnce(T) -> C> DynChoice for RightCoBind<T, F> {
113    type Left = T::Left;
114    type Right = C;
115
116    fn into_left(self: Box<Self>) -> T::Left {
117        self.choice.left()
118    }
119
120    fn into_right(self: Box<Self>) -> C {
121        (self.cobind)(self.choice)
122    }
123}
124
125use impl_trait_for_tuples::*;
126
127#[impl_for_tuples(0, 16)]
128impl DynChoice for Tuple {
129    for_tuples!( type Left = ( #( Tuple::Left ),* ); );
130    for_tuples!( type Right = ( #( Tuple::Right ),* ); );
131
132    fn into_left(self: Box<Self>) -> Self::Left {
133        for_tuples!( ( #( self.Tuple.left() ),* ) )
134    }
135
136    fn into_right(self: Box<Self>) -> Self::Right {
137        for_tuples!( ( #( self.Tuple.right() ),* ) )
138    }
139}