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    #[expect(missing_docs)]
7    type Output;
8
9    #[expect(missing_docs)]
10    fn extend(self, item: T) -> Self::Output;
11}
12
13///////////////////////////////////////////////////////////////////////////////
14
15macro_rules! impl_extend_tuple {
16    ($($T:ident),*) => {
17        impl<$($T,)* U> Extend<U> for ($($T,)*) {
18            type Output = ($($T,)* U,);
19
20            #[allow(non_snake_case)]
21            fn extend(self, item: U) -> Self::Output {
22                let ($($T,)*) = self;
23                ($($T,)* item,)
24            }
25        }
26    };
27}
28
29impl_extend_tuple! {}
30impl_extend_tuple! { T0 }
31impl_extend_tuple! { T0, T1 }
32impl_extend_tuple! { T0, T1, T2 }
33impl_extend_tuple! { T0, T1, T2, T3 }
34impl_extend_tuple! { T0, T1, T2, T3, T4 }
35impl_extend_tuple! { T0, T1, T2, T3, T4, T5 }
36impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6 }
37impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7 }
38impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8 }
39impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 }
40impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 }
41impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 }
42impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 }
43impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 }
44impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 }
45impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 }
46impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16 }
47impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17 }
48impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18 }
49impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19 }
50impl_extend_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
60impl_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 }
61impl_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 }
62
63///////////////////////////////////////////////////////////////////////////////
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    fn assert_ty<T>(_: T) {}
70
71    #[test]
72    fn test_extend_empty() {
73        let args = ();
74        assert_ty::<(i32,)>(args.extend(1));
75    }
76
77    #[test]
78    fn test_extend() {
79        let args = (1, 2, 3);
80        assert_ty::<(i32, i32, i32, i32)>(args.extend(4));
81    }
82}