fast_tuple/
lib.rs

1#![doc(html_root_url = "https://docs.rs/fast_tuple/0.1.3/")]
2#![no_std]
3
4//! This procedural macro crate serves the purporse of construct a tuple thought the array-like [T; N] syntax,where T can be a type
5//! for annotate or an expression and N is the number of times T repeats. 
6//!
7//! This macro is **no_std** with debug assertions disabled.
8
9extern crate alloc;
10extern crate proc_macro;
11
12#[cfg(debug_assertions)]
13extern crate std;
14
15use alloc::string::{String, ToString};
16use proc_macro::TokenStream;
17
18/// A tuple array-like constructor tuple!(T; N).
19///
20/// See [crate docs](./index.html) for more details.
21///
22/// # Errors
23/// 
24/// All the failures of this macro throw crate-defined compiler errors. In addition,when debug assertions are enabled
25/// the tuples with N longer than 12 will print a error message warning that the standard library traits will not be auto-implemented.
26#[proc_macro]
27pub fn tuple(ts: TokenStream) -> TokenStream {
28    let ts = ts.to_string();
29    let mut expansion = String::new();
30
31    let index = ts.rfind(";").unwrap_or_else(|| {
32        expansion.push_str("compile_error!(\"Expression does not hold any `;`\")");
33        0
34    });
35
36    if expansion != "" {
37        return expansion.parse().unwrap();
38    }
39
40    if index == 0 {
41        return String::from("compile_error!(\"Expected expression or type behind the `;` but there's no one\")").parse().unwrap();
42    }
43
44    let (mut value, mut arity) = ts.split_at(index);
45    value = value.trim();
46    arity = &arity[1..];
47    arity = arity.trim();
48
49    let arity: usize = arity.parse().unwrap_or_else(|_| {
50        expansion.push_str("compile_error!(\"Invalid numeric constant after `;`\")");
51        0
52    });
53
54    if expansion != "" {
55        return expansion.parse().unwrap();
56    }
57
58    if arity == 0 {
59        return String::from("compile_error!(\"The length cannot be zero use `()` instead\")").parse().unwrap();
60    }
61
62    if cfg!(debug_assertions) && arity > 12 {
63        std::eprintln!("tuples of arity of more than 12({}) has no standard traits implemented, this message is only show with debug_assertions enabled.", arity);
64    }
65
66    expansion.reserve(value.len()*arity + arity + 1);
67
68    expansion.push_str("(");
69
70    for _ in 0..arity - 1 {
71        expansion.push_str(value);
72        expansion.push_str(",");
73    }
74
75    expansion.push_str(value);
76    expansion.push_str(")");
77
78    expansion.parse().unwrap()
79}