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