| 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)); |
| } |
| } |
| } |
| } |
| } |