1#![no_std]
2
3pub trait TupleTranspose {
4 type Output;
5 fn transpose(self) -> Self::Output;
6}
7
8macro_rules! define_tuple_transpose {
9 ($($v:ident: $T:ident),+ $(,)?) => {
10 impl<$($T),+, E> TupleTranspose for ($(Result<$T, E>,)+) {
11 type Output = Result<($($T,)+), E>;
12 fn transpose(self) -> Self::Output {
13 let ($($v,)+) = self;
14 Ok(($($v?,)+))
15 }
16 }
17
18 impl<$($T),+> TupleTranspose for ($(Option<$T>,)+) {
19 type Output = Option<($($T,)+)>;
20 fn transpose(self) -> Self::Output {
21 let ($($v,)+) = self;
22 Some(($($v?,)+))
23 }
24 }
25 }
26}
27
28define_tuple_transpose!(v0: T0);
29define_tuple_transpose!(v0: T0, v1: T1);
30define_tuple_transpose!(v0: T0, v1: T1, v2: T2);
31define_tuple_transpose!(v0: T0, v1: T1, v2: T2, v3: T3);
32define_tuple_transpose!(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4);
33define_tuple_transpose!(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5);
34define_tuple_transpose!(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6);
35define_tuple_transpose!(v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7);
36define_tuple_transpose!(
37 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
38 v8: T8,
39);
40define_tuple_transpose!(
41 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
42 v8: T8, v9: T9,
43);
44define_tuple_transpose!(
45 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
46 v8: T8, v9: T9, v10: T10,
47);
48define_tuple_transpose!(
49 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
50 v8: T8, v9: T9, v10: T10, v11: T11,
51);
52define_tuple_transpose!(
53 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
54 v8: T8, v9: T9, v10: T10, v11: T11, v12: T12,
55);
56define_tuple_transpose!(
57 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
58 v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13,
59);
60define_tuple_transpose!(
61 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
62 v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14,
63);
64define_tuple_transpose!(
65 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
66 v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15,
67);
68define_tuple_transpose!(
69 v0: T0, v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7,
70 v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16,
71);
72
73#[cfg(test)]
74mod tests {
75 use super::TupleTranspose;
76
77 #[test]
78 fn test_ok_ok() {
79 assert_eq!((Ok::<_, ()>(1u32), Ok(2.0f32)).transpose(), Ok((1u32, 2.0f32)));
80 }
81
82 #[test]
83 fn test_ok_err() {
84 assert_eq!((Ok(1u32), Err::<u64, _>(2.0f32)).transpose(), Err(2.0f32));
85 }
86
87 #[test]
88 fn test_err_ok() {
89 assert_eq!((Err::<i32, _>(1u32), Ok(2.0f32)).transpose(), Err(1u32));
90 }
91
92 #[test]
93 fn test_some_some() {
94 assert_eq!((Some(1u32), Some(2.0f32)).transpose(), Some((1u32, 2.0f32)));
95 }
96
97 #[test]
98 fn test_some_none() {
99 assert_eq!((Some(1u32), None::<f32>).transpose(), None::<(u32, f32)>);
100 }
101
102 #[test]
103 fn test_none_some() {
104 assert_eq!((None::<u32>, Some(2.0f32)).transpose(), None::<(u32, f32)>);
105 }
106}