sea_query/value/
value_tuple.rs

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