1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! Generalized free tuples.
//!
//! The `GTup` type is used to create generalized tuples. Because **Rust** doesn’t support type
//! operators, `GTup` is used to create static tuples that can have an arbitrary size while
//! remaining of the same recursive form. That’s very useful to implement traits for any kind of
//! tuples.
//!
//! Feel free to dig in the documention of `GTup` for further details.

/// The generalized free tuple.
///
/// You can create arbitrary chains by nesting `GTup` types, or use the `gtup!` type macro.
///
/// > Note: `GTup` is right-associative.
///
/// # Examples
///
/// ```
/// type Foo = GTup<i32, GTup<bool, f32>>;
/// type Bar = GTup<GTup<i32, bool>, f32>;
/// type Zoo = gtup![i32, bool, f32]; // Zoo == Foo
/// ```
pub struct GTup<A, B>(pub A, pub B);

#[macro_export]
macro_rules! gtup_ty {
    ($t:ty) => { $t };
    ($a:ty, $($r:tt)*) => { GTup<$a, gtup_ty!($($r)*)> }
}

#[macro_export]
macro_rules! gtup_value {
    ($t:expr) => { $t };
    ($a:expr, $($r:tt)*) => { GTup($a, gtup_value!($($r)*)) }
}

/// Generalized free tuple macro.
///
/// If your compiler supports the `type_macros`*feature*, you can use this macro to create tuples 
/// without the syntactic nesting boilerplate.
///
/// Furthermore, you can create values with this macro as well.
///
/// # Examples
///
/// ```
/// // type
/// type Foo = GTup<i32, Chain<bool, f32>>;
/// type Zoo = gtup!(:i32, bool, f32); // exactly the same type
///
/// // value
/// let triple = gtup!(42, false, 3.1415);
/// ```
#[macro_export]
macro_rules! gtup {
    (:$($a:tt)*) => { gtup_ty!($($a)*) };
    ($($a:tt)*) => { gtup_value!($($a)*) }
}