numext_fixed_uint_hack/
lib.rs

1// Copyright 2018-2019 Cryptape Technologies LLC.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! This is a internal crate used by [numext-fixed-uint].
10//!
11//! **Notice:
12//! You should NOT use this crate directly.
13//! Please use [numext-fixed-uint] instead of this crate.**
14//!
15//! [numext-fixed-uint]: https://docs.rs/numext-fixed-uint
16
17extern crate nfuint_core;
18
19extern crate proc_macro;
20
21use quote::quote;
22use syn::parse_macro_input;
23
24macro_rules! impl_func {
25    ($(($name:ident, $type:ident),)+) => {
26        $(impl_func!($name, $type);)+
27    };
28    ($(($name:ident, $type:ident)),+) => {
29        $(impl_func!($name, $type);)+
30    };
31    ($name:ident, $type:ident) =>    {
32        #[proc_macro]
33        pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
34            let input = parse_macro_input!(input as syn::LitStr);
35            let expanded = {
36                let input = input.value().replace("_", "");
37                if input.is_empty() {
38                    panic!("Input is empty.");
39                }
40                let (value_result, input_type) = if input.len() < 3 {
41                    (nfuint_core::$type::from_dec_str(&input), "decimal")
42                } else {
43                    match &input[..2] {
44                        "0b" => (nfuint_core::$type::from_bin_str(&input[2..]), "binary"),
45                        "0o" => (nfuint_core::$type::from_oct_str(&input[2..]), "octal"),
46                        "0x" => (nfuint_core::$type::from_hex_str(&input[2..]), "hexadecimal"),
47                        _ => (nfuint_core::$type::from_dec_str(&input), "decimal"),
48                    }
49                };
50                let value = value_result.unwrap_or_else(|err| {
51                    panic!("Failed to parse the input {} string: {}", input_type, err);
52                });
53                let eval_str = format!("{:?}", value);
54                let eval_ts: proc_macro2::TokenStream = eval_str.parse().unwrap_or_else(|_| {
55                    panic!("Failed to parse the string [{}] to TokenStream.", eval_str);
56                });
57                quote!(#eval_ts)
58            };
59            expanded.into()
60        }
61    };
62}
63
64impl_func!(
65    (u128, U128),
66    (u160, U160),
67    (u224, U224),
68    (u256, U256),
69    (u384, U384),
70    (u512, U512),
71    (u520, U520),
72    (u1024, U1024),
73    (u2048, U2048),
74    (u4096, U4096),
75);