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