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