enum_ordinalize/
big_int_wrapper.rs

1use num_bigint::BigInt;
2use num_traits::{Signed, ToPrimitive};
3use proc_macro2::{Literal, TokenStream};
4use quote::{quote, ToTokens, TokenStreamExt};
5use syn::Expr;
6
7pub(crate) enum BigIntWrapper<'a> {
8    Integer(BigInt),
9    Constant(&'a Expr, usize),
10}
11
12impl<'a> From<BigInt> for BigIntWrapper<'a> {
13    #[inline]
14    fn from(v: BigInt) -> BigIntWrapper<'a> {
15        BigIntWrapper::Integer(v)
16    }
17}
18
19impl<'a> From<(&'a Expr, usize)> for BigIntWrapper<'a> {
20    #[inline]
21    fn from((expr, counter): (&'a Expr, usize)) -> BigIntWrapper<'a> {
22        BigIntWrapper::Constant(expr, counter)
23    }
24}
25
26impl<'a> ToTokens for BigIntWrapper<'a> {
27    #[inline]
28    fn to_tokens(&self, tokens: &mut TokenStream) {
29        match self {
30            BigIntWrapper::Integer(v) => {
31                let lit = if v.is_negative() {
32                    Literal::i128_unsuffixed(v.to_i128().unwrap())
33                } else {
34                    Literal::u128_unsuffixed(v.to_u128().unwrap())
35                };
36
37                tokens.append(lit);
38            },
39            BigIntWrapper::Constant(expr, counter) => {
40                let counter = *counter;
41
42                if counter > 0 {
43                    tokens.extend(quote!(#expr +));
44                    tokens.append(Literal::usize_unsuffixed(counter));
45                } else {
46                    tokens.extend(quote!(#expr));
47                }
48            },
49        }
50    }
51}