ark_ff_macros/
utils.rs

1use std::str::FromStr;
2
3use num_bigint::{BigInt, Sign};
4use proc_macro::TokenStream;
5use syn::{Expr, Lit};
6
7pub fn parse_string(input: TokenStream) -> Option<String> {
8    let input: Expr = syn::parse(input).unwrap();
9    let input = if let Expr::Group(syn::ExprGroup { expr, .. }) = input {
10        expr
11    } else {
12        panic!("could not parse");
13    };
14    match *input {
15        Expr::Lit(expr_lit) => match expr_lit.lit {
16            Lit::Str(s) => Some(s.value()),
17            _ => None,
18        },
19        _ => None,
20    }
21}
22
23pub fn str_to_limbs(num: &str) -> (bool, Vec<String>) {
24    let (sign, limbs) = str_to_limbs_u64(num);
25    (sign, limbs.into_iter().map(|l| format!("{l}u64")).collect())
26}
27
28pub fn str_to_limbs_u64(num: &str) -> (bool, Vec<u64>) {
29    let (sign, digits) = BigInt::from_str(num)
30        .expect("could not parse to bigint")
31        .to_radix_le(16);
32    let limbs = digits
33        .chunks(16)
34        .map(|chunk| {
35            let mut this = 0u64;
36            for (i, hexit) in chunk.iter().enumerate() {
37                this += (*hexit as u64) << (4 * i);
38            }
39            this
40        })
41        .collect::<Vec<_>>();
42
43    let sign_is_positive = sign != Sign::Minus;
44    (sign_is_positive, limbs)
45}