sea_query/value/
value_tuple.rs

1use super::*;
2
3#[derive(Clone, Debug, PartialEq)]
4#[cfg_attr(feature = "hashable-value", derive(Hash, Eq))]
5pub enum ValueTuple {
6    One(Value),
7    Two(Value, Value),
8    Three(Value, Value, Value),
9    Many(Vec<Value>),
10}
11
12#[derive(Debug)]
13pub struct ValueTupleIter<'a> {
14    value: &'a ValueTuple,
15    index: usize,
16}
17
18pub trait IntoValueTuple: Into<ValueTuple> {
19    fn into_value_tuple(self) -> ValueTuple {
20        self.into()
21    }
22}
23
24impl ValueTuple {
25    pub fn arity(&self) -> usize {
26        match self {
27            Self::One(_) => 1,
28            Self::Two(_, _) => 2,
29            Self::Three(_, _, _) => 3,
30            Self::Many(vec) => vec.len(),
31        }
32    }
33
34    pub fn iter(&self) -> ValueTupleIter<'_> {
35        ValueTupleIter::new(self)
36    }
37}
38
39impl IntoIterator for ValueTuple {
40    type Item = Value;
41    type IntoIter = std::vec::IntoIter<Self::Item>;
42
43    fn into_iter(self) -> Self::IntoIter {
44        match self {
45            ValueTuple::One(v) => vec![v].into_iter(),
46            ValueTuple::Two(v, w) => vec![v, w].into_iter(),
47            ValueTuple::Three(u, v, w) => vec![u, v, w].into_iter(),
48            ValueTuple::Many(vec) => vec.into_iter(),
49        }
50    }
51}
52
53impl<'a> ValueTupleIter<'a> {
54    fn new(value: &'a ValueTuple) -> Self {
55        Self { value, index: 0 }
56    }
57}
58
59impl<'a> Iterator for ValueTupleIter<'a> {
60    type Item = &'a Value;
61
62    fn next(&mut self) -> Option<Self::Item> {
63        let result = match self.value {
64            ValueTuple::One(a) => {
65                if self.index == 0 {
66                    Some(a)
67                } else {
68                    None
69                }
70            }
71            ValueTuple::Two(a, b) => match self.index {
72                0 => Some(a),
73                1 => Some(b),
74                _ => None,
75            },
76            ValueTuple::Three(a, b, c) => match self.index {
77                0 => Some(a),
78                1 => Some(b),
79                2 => Some(c),
80                _ => None,
81            },
82            ValueTuple::Many(vec) => vec.get(self.index),
83        };
84        self.index += 1;
85        result
86    }
87}
88
89impl<T> IntoValueTuple for T where T: Into<ValueTuple> {}
90
91impl<V> From<V> for ValueTuple
92where
93    V: Into<Value>,
94{
95    fn from(value: V) -> Self {
96        ValueTuple::One(value.into())
97    }
98}
99
100impl<V, W> From<(V, W)> for ValueTuple
101where
102    V: Into<Value>,
103    W: Into<Value>,
104{
105    fn from(value: (V, W)) -> Self {
106        ValueTuple::Two(value.0.into(), value.1.into())
107    }
108}
109
110impl<U, V, W> From<(U, V, W)> for ValueTuple
111where
112    U: Into<Value>,
113    V: Into<Value>,
114    W: Into<Value>,
115{
116    fn from(value: (U, V, W)) -> Self {
117        ValueTuple::Three(value.0.into(), value.1.into(), value.2.into())
118    }
119}
120
121macro_rules! impl_into_value_tuple {
122    ( $($idx:tt : $T:ident),+ $(,)? ) => {
123        impl< $($T),+ > From<( $($T),+ )> for ValueTuple
124        where
125            $($T: Into<Value>),+
126        {
127            fn from(value: ( $($T),+ )) -> Self  {
128                ValueTuple::Many(vec![
129                    $(value.$idx.into()),+
130                ])
131            }
132        }
133    };
134}
135
136impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3);
137impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4);
138impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5);
139impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6);
140impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7);
141impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8);
142impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9);
143impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9, 10:T10);
144impl_into_value_tuple!(0:T0, 1:T1, 2:T2, 3:T3, 4:T4, 5:T5, 6:T6, 7:T7, 8:T8, 9:T9, 10:T10, 11:T11);
145
146pub trait FromValueTuple: Sized {
147    fn from_value_tuple<I>(i: I) -> Self
148    where
149        I: IntoValueTuple;
150}
151
152impl<V> FromValueTuple for V
153where
154    V: Into<Value> + ValueType,
155{
156    fn from_value_tuple<I>(i: I) -> Self
157    where
158        I: IntoValueTuple,
159    {
160        match i.into_value_tuple() {
161            ValueTuple::One(u) => u.unwrap(),
162            _ => panic!("not ValueTuple::One"),
163        }
164    }
165}
166
167impl<V, W> FromValueTuple for (V, W)
168where
169    V: Into<Value> + ValueType,
170    W: Into<Value> + ValueType,
171{
172    fn from_value_tuple<I>(i: I) -> Self
173    where
174        I: IntoValueTuple,
175    {
176        match i.into_value_tuple() {
177            ValueTuple::Two(v, w) => (v.unwrap(), w.unwrap()),
178            _ => panic!("not ValueTuple::Two"),
179        }
180    }
181}
182
183impl<U, V, W> FromValueTuple for (U, V, W)
184where
185    U: Into<Value> + ValueType,
186    V: Into<Value> + ValueType,
187    W: Into<Value> + ValueType,
188{
189    fn from_value_tuple<I>(i: I) -> Self
190    where
191        I: IntoValueTuple,
192    {
193        match i.into_value_tuple() {
194            ValueTuple::Three(u, v, w) => (u.unwrap(), v.unwrap(), w.unwrap()),
195            _ => panic!("not ValueTuple::Three"),
196        }
197    }
198}
199
200macro_rules! impl_from_value_tuple {
201    ( $len:expr, $($T:ident),+ $(,)? ) => {
202        impl< $($T),+ > FromValueTuple for ( $($T),+ )
203        where
204            $($T: Into<Value> + ValueType),+
205        {
206            fn from_value_tuple<Z>(i: Z) -> Self
207            where
208                Z: IntoValueTuple,
209            {
210                match i.into_value_tuple() {
211                    ValueTuple::Many(vec) if vec.len() == $len => {
212                        let mut iter = vec.into_iter();
213                        (
214                            $(<$T as ValueType>::unwrap(iter.next().unwrap())),+
215                        )
216                    }
217                    _ => panic!("not ValueTuple::Many with length of {}", $len),
218                }
219            }
220        }
221    };
222}
223
224impl_from_value_tuple!(4, T0, T1, T2, T3);
225impl_from_value_tuple!(5, T0, T1, T2, T3, T4);
226impl_from_value_tuple!(6, T0, T1, T2, T3, T4, T5);
227impl_from_value_tuple!(7, T0, T1, T2, T3, T4, T5, T6);
228impl_from_value_tuple!(8, T0, T1, T2, T3, T4, T5, T6, T7);
229impl_from_value_tuple!(9, T0, T1, T2, T3, T4, T5, T6, T7, T8);
230impl_from_value_tuple!(10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
231impl_from_value_tuple!(11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
232impl_from_value_tuple!(12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);