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);