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
use num_bigint::BigInt;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::Expr;
use num_traits::{Signed, ToPrimitive};
use proc_macro2::{Literal, TokenStream};
pub(crate) enum BigIntWrapper<'a> {
Integer(BigInt),
Constant(&'a Expr, usize),
}
impl<'a> From<BigInt> for BigIntWrapper<'a> {
#[inline]
fn from(v: BigInt) -> BigIntWrapper<'a> {
BigIntWrapper::Integer(v)
}
}
impl<'a> From<(&'a Expr, usize)> for BigIntWrapper<'a> {
#[inline]
fn from((expr, counter): (&'a Expr, usize)) -> BigIntWrapper<'a> {
BigIntWrapper::Constant(expr, counter)
}
}
impl<'a> ToTokens for BigIntWrapper<'a> {
#[inline]
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
BigIntWrapper::Integer(v) => {
let lit = if v.is_negative() {
Literal::i128_unsuffixed(v.to_i128().unwrap())
} else {
Literal::u128_unsuffixed(v.to_u128().unwrap())
};
tokens.append(lit);
}
BigIntWrapper::Constant(expr, counter) => {
let counter = *counter;
if counter > 0 {
tokens.extend(quote!(#expr +));
tokens.append(Literal::usize_unsuffixed(counter));
} else {
tokens.extend(quote!(#expr));
}
}
}
}
}