const_arith_macros_178/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use syn::{parse_macro_input, LitInt};
5
6// Debug :)
7#[allow(unused)]
8fn print_type_of<T>(_: &T) -> &'static str {
9    std::any::type_name::<T>()
10}
11
12fn int_to_hex_codes(input: LitInt) -> Vec<String> {
13    let input_value = input.base10_digits();
14    let parsed_value = match input_value.parse::<u32>() {
15        Ok(value) => value,
16        Err(_) => panic!("Input is not of correct type: {}", input_value),
17    };
18
19    // panic!("Parsed value: {}, type: {}", num, print_type_of(&num));
20    let mut hex_digits: Vec<String> = Vec::new();
21    let mut num = parsed_value;
22
23    while num > 0 {
24        let hex_digit = num & 0xF;
25        hex_digits.push(format!("_{:X}", hex_digit));
26        num >>= 4;
27    }
28
29    while hex_digits.len() < 8 {
30        hex_digits.push(String::from("_0"));
31    }
32
33    return hex_digits;
34}
35
36// Parses a literal integer into its typed counterpart. Panics inline if the input is not a u32
37#[doc(hidden)]
38#[proc_macro]
39pub fn parse_integer_inner(token: TokenStream) -> TokenStream {
40    let input = parse_macro_input!(token as LitInt);
41    let hex_digits = int_to_hex_codes(input);
42    let joined = hex_digits.join(", ");
43
44    // let result = format!("Integer::<{}> {{ _m0: PhantomData, _m1: PhantomData, _m2: PhantomData, _m3: PhantomData, _m4: PhantomData, _m5: PhantomData, _m6: PhantomData, _m7: PhantomData }}", hex_digits.join(", "));
45    let result = format!("TypedInteger::<{}>  {{ _m0: PhantomData,  _m1: PhantomData,  _m2: PhantomData,  _m3: PhantomData, _m4: PhantomData,  _m5: PhantomData,  _m6: PhantomData,  _m7: PhantomData }}", joined);
46
47    // panic!("{}", result);
48    result.parse().unwrap()
49}
50
51// Assert the typed integer equals the number you provided
52#[doc(hidden)]
53#[proc_macro]
54pub fn typed_assert_eq_inner(token: TokenStream) -> TokenStream {
55    let input = parse_macro_input!(token as LitInt);
56    // Use an iterator so that strings does not have to be copied
57    let mut hex_digits = int_to_hex_codes(input).into_iter();
58    let s0 = hex_digits.next().unwrap();
59    let s1 = hex_digits.next().unwrap();
60    let s2 = hex_digits.next().unwrap();
61    let s3 = hex_digits.next().unwrap();
62    let s4 = hex_digits.next().unwrap();
63    let s5 = hex_digits.next().unwrap();
64    let s6 = hex_digits.next().unwrap();
65    let s7 = hex_digits.next().unwrap();
66    let result = format!(r"
67    fn asserting<T, S0, S1, S2, S3, S4, S5, S6, S7>(_: &T) where
68        S0: Hex,
69        S1: Hex,
70        S2: Hex,
71        S3: Hex,
72        S4: Hex,
73        S5: Hex,
74        S6: Hex,
75        S7: Hex,
76        T: IsInteger<Hex0 = S0, Hex1 = S1, Hex2 = S2, Hex3 = S3, Hex4 = S4, Hex5 = S5, Hex6 = S6, Hex7 = S7>,
77        S0: HexAssertEqual<{}>,
78        S1: HexAssertEqual<{}>,
79        S2: HexAssertEqual<{}>,
80        S3: HexAssertEqual<{}>,
81        S4: HexAssertEqual<{}>,
82        S5: HexAssertEqual<{}>,
83        S6: HexAssertEqual<{}>,
84        S7: HexAssertEqual<{}>,
85    {{}}", s0, s1, s2, s3, s4, s5, s6, s7);
86    result.parse().unwrap()
87}