big_int_proc/
lib.rs

1use proc_macro::TokenStream;
2use quote::{format_ident, quote};
3use syn::*;
4
5#[proc_macro_derive(BigIntTraits)]
6pub fn auto_big_int_derive(input: TokenStream) -> TokenStream {
7    let ast = parse_macro_input!(input as DeriveInput);
8    let name = &ast.ident;
9    let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl();
10
11    let int_conversions = [
12        (
13            "from_i128_inner",
14            "into_i128_inner",
15            "i128",
16            ["i128", "i64", "i32", "i16", "i8", "isize"],
17        ),
18        (
19            "from_u128_inner",
20            "into_u128_inner",
21            "u128",
22            ["u128", "u64", "u32", "u16", "u8", "usize"],
23        ),
24    ]
25    .into_iter()
26    .map(|(from, into, from_target_type, int_types)| {
27        let from = format_ident!("{from}");
28        let into = format_ident!("{into}");
29        let from_target_type = format_ident!("{from_target_type}");
30        int_types.map(|int| {
31            let int = format_ident!("{int}");
32            quote! {
33                impl #impl_generics ::std::convert::From<#int> for #name #ty_generics #where_clause {
34                    fn from(value: #int) -> Self {
35                        <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
36                            <#name #ty_generics as ::big_int::BigInt<BASE>>::#from(value as #from_target_type)
37                        )
38                    }
39                }
40
41                impl #impl_generics ::std::convert::From<#name #ty_generics> for #int {
42                    fn from(value: #name #ty_generics) -> Self {
43                        <#name #ty_generics as ::big_int::BigInt<BASE>>::#into(value) as #int
44                    }
45                }
46            }
47        })
48    })
49    .flatten();
50
51    let gen = quote! {
52        impl #impl_generics ::big_int::get_back::GetBack for #name #ty_generics #where_clause {
53            type Item = ::big_int::Digit;
54
55            fn get_back(&self, index: usize) -> Option<::big_int::Digit> {
56                <#name #ty_generics as ::big_int::BigInt<BASE>>::get_back_inner(self, index)
57            }
58        }
59
60        impl #impl_generics ::std::default::Default for #name #ty_generics #where_clause {
61            fn default() -> Self {
62                <#name #ty_generics as ::big_int::BigInt<BASE>>::default_inner()
63            }
64        }
65
66        impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause {
67            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68                <#name #ty_generics as ::big_int::BigInt<BASE>>::fmt_inner(self, f)
69            }
70        }
71
72        impl #impl_generics ::std::cmp::PartialOrd for #name #ty_generics #where_clause {
73            fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
74                <#name #ty_generics as ::big_int::BigInt<BASE>>::partial_cmp_inner(self, other)
75            }
76        }
77
78        impl #impl_generics ::std::cmp::Ord for #name #ty_generics #where_clause {
79            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
80                <#name #ty_generics as ::big_int::BigInt<BASE>>::cmp_inner(self, other)
81            }
82        }
83
84        impl #impl_generics ::std::cmp::PartialEq for #name #ty_generics #where_clause {
85            fn eq(&self, other: &Self) -> bool {
86                <#name #ty_generics as ::big_int::BigInt<BASE>>::eq_inner(self, other)
87            }
88        }
89
90        impl #impl_generics ::std::cmp::Eq for #name #ty_generics #where_clause {}
91
92        impl #impl_generics ::std::ops::Neg for #name #ty_generics #where_clause {
93            type Output = Self;
94
95            fn neg(self) -> Self::Output {
96                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
97                    <#name #ty_generics as ::big_int::BigInt<BASE>>::neg_inner(self)
98                )
99            }
100        }
101
102        impl #impl_generics ::std::ops::Add for #name #ty_generics #where_clause {
103            type Output = Self;
104
105            fn add(self, rhs: Self) -> Self::Output {
106                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
107                    <#name #ty_generics as ::big_int::BigInt<BASE>>::add_inner::<Self, Self>(self, rhs)
108                )
109            }
110        }
111
112        impl #impl_generics ::std::ops::AddAssign for #name #ty_generics #where_clause {
113            fn add_assign(&mut self, rhs: Self) {
114                unsafe {
115                    <#name #ty_generics as ::big_int::BigInt<BASE>>::add_assign_inner(self, rhs);
116                }
117                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
118            }
119        }
120
121        impl #impl_generics ::std::ops::Sub for #name #ty_generics #where_clause {
122            type Output = Self;
123
124            fn sub(mut self, rhs: Self) -> Self::Output {
125                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
126                    <#name #ty_generics as ::big_int::BigInt<BASE>>::sub_inner::<Self, Self>(self, rhs)
127                )
128            }
129        }
130
131        impl #impl_generics ::std::ops::SubAssign for #name #ty_generics #where_clause {
132            fn sub_assign(&mut self, rhs: Self) {
133                unsafe {
134                    <#name #ty_generics as ::big_int::BigInt<BASE>>::sub_assign_inner(self, rhs)
135                }
136                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
137            }
138        }
139
140        impl #impl_generics ::std::ops::Mul for #name #ty_generics #where_clause {
141            type Output = Self;
142
143            fn mul(mut self, rhs: Self) -> Self::Output {
144                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
145                    <#name #ty_generics as ::big_int::BigInt<BASE>>::mul_inner::<Self, Self>(self, rhs)
146                )
147            }
148        }
149
150        impl #impl_generics ::std::ops::MulAssign for #name #ty_generics #where_clause {
151            fn mul_assign(&mut self, rhs: Self) {
152                unsafe {
153                    <#name #ty_generics as ::big_int::BigInt<BASE>>::mul_assign_inner(self, rhs)
154                }
155                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
156            }
157        }
158
159        impl #impl_generics ::std::ops::Div for #name #ty_generics #where_clause {
160            type Output = Self;
161
162            fn div(self, rhs: Self) -> Self::Output {
163                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
164                    <#name #ty_generics as ::big_int::BigInt<BASE>>::div_inner::<Self, Self>(self, rhs)
165                )
166            }
167        }
168
169        impl #impl_generics ::std::ops::DivAssign for #name #ty_generics #where_clause {
170            fn div_assign(&mut self, rhs: Self) {
171                unsafe {
172                    <#name #ty_generics as ::big_int::BigInt<BASE>>::div_assign_inner(self, rhs)
173                }
174                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
175            }
176        }
177
178        impl #impl_generics ::std::ops::Shl for #name #ty_generics #where_clause {
179            type Output = Self;
180
181            fn shl(self, rhs: Self) -> Self::Output {
182                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
183                    <#name #ty_generics as ::big_int::BigInt<BASE>>::shl_inner(self, rhs.into())
184                )
185            }
186        }
187
188        impl #impl_generics ::std::ops::ShlAssign for #name #ty_generics #where_clause {
189            fn shl_assign(&mut self, rhs: Self) {
190                unsafe {
191                    <#name #ty_generics as ::big_int::BigInt<BASE>>::shl_assign_inner(self, rhs.into())
192                }
193                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
194            }
195        }
196
197        impl #impl_generics ::std::ops::Shr for #name #ty_generics #where_clause {
198            type Output = Self;
199
200            fn shr(self, rhs: Self) -> Self::Output {
201                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
202                    <#name #ty_generics as ::big_int::BigInt<BASE>>::shr_inner(self, rhs.into())
203                )
204            }
205        }
206
207        impl #impl_generics ::std::ops::ShrAssign for #name #ty_generics #where_clause {
208            fn shr_assign(&mut self, rhs: Self) {
209                unsafe {
210                    <#name #ty_generics as ::big_int::BigInt<BASE>>::shr_assign_inner(self, rhs.into())
211                }
212                <#name #ty_generics as ::big_int::BigInt<BASE>>::normalize(self);
213            }
214        }
215
216        impl #impl_generics ::std::str::FromStr for #name #ty_generics #where_clause {
217            type Err = ::big_int::error::BigIntError;
218
219            fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
220                <#name #ty_generics as ::big_int::BigInt<BASE>>::from_str_inner(s).map(|i|
221                    <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(i)
222                )
223            }
224        }
225
226        impl #impl_generics ::std::iter::FromIterator<::big_int::Digit> for #name #ty_generics #where_clause {
227            fn from_iter<T: IntoIterator<Item = ::big_int::Digit>>(iter: T) -> Self {
228                <<#name #ty_generics as ::big_int::BigInt<BASE>>::Denormal as ::big_int::Unwrap<#name #ty_generics>>::unwrap(
229                    <#name #ty_generics as ::big_int::BigInt<BASE>>::from_iter_inner(iter)
230                )
231            }
232        }
233
234        impl #impl_generics ::std::iter::IntoIterator for #name #ty_generics #where_clause {
235            type Item = ::big_int::Digit;
236            type IntoIter = ::big_int::BigIntIntoIter<BASE, Self>;
237
238            fn into_iter(self) -> Self::IntoIter {
239                ::big_int::BigIntIntoIter(self)
240            }
241        }
242
243        impl #impl_generics ::std::convert::From<::std::vec::Vec<::big_int::Digit>> for #name #ty_generics #where_clause {
244            fn from(value: ::std::vec::Vec<::big_int::Digit>) -> Self {
245                value.into_iter().collect()
246            }
247        }
248
249        #(#int_conversions)*
250    };
251    gen.into()
252}