Skip to main content

magic_args/
extend.rs

1/// Extend a type by another type `T`.
2///
3/// This trait is mainly used for extending tuples but you can implement it for
4/// whatever you like.
5pub trait Extend<T> {
6    type Output;
7
8    fn extend(self, item: T) -> Self::Output;
9}
10
11///////////////////////////////////////////////////////////////////////////////
12
13macro_rules! impl_extend_tuple {
14    ($($T:ident),*) => {
15        impl<$($T,)* U> Extend<U> for ($($T,)*) {
16            type Output = ($($T,)* U,);
17
18            #[allow(non_snake_case)]
19            fn extend(self, item: U) -> Self::Output {
20                let ($($T,)*) = self;
21                ($($T,)* item,)
22            }
23        }
24    };
25}
26
27impl_extend_tuple! {}
28impl_extend_tuple! { T0 }
29impl_extend_tuple! { T0, T1 }
30impl_extend_tuple! { T0, T1, T2 }
31impl_extend_tuple! { T0, T1, T2, T3 }
32impl_extend_tuple! { T0, T1, T2, T3, T4 }
33impl_extend_tuple! { T0, T1, T2, T3, T4, T5 }
34impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6 }
35impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7 }
36impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8 }
37impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 }
38impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 }
39impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 }
40impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 }
41impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 }
42impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 }
43impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 }
44impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 }
45impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 }
46impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 }
47impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 }
48impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20 }
49impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21 }
50impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22 }
51impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23 }
52impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24 }
53impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25 }
54impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26 }
55impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27 }
56impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28 }
57impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29 }
58impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30 }
59impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31 }
60
61///////////////////////////////////////////////////////////////////////////////
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    fn assert_ty<T>(_: T) {}
68
69    #[test]
70    fn test_extend_empty() {
71        let args = ();
72        assert_ty::<(i32,)>(args.extend(1));
73    }
74
75    #[test]
76    fn test_extend() {
77        let args = (1, 2, 3);
78        assert_ty::<(i32, i32, i32, i32)>(args.extend(4));
79    }
80}