astro-float-macro 0.4.6

Macros for multiple precision floating point numbers library astro-float.
Documentation
//! Utility functions.

use astro_float_num::BigFloat;
use astro_float_num::Consts;
use astro_float_num::Radix;
use astro_float_num::RoundingMode;
use proc_macro2::Span;
use proc_macro2::TokenStream;
use quote::quote;
use syn::spanned::Spanned;
use syn::Error;
use syn::ExprCall;

pub fn str_to_bigfloat_expr(s: &str, span: Span, cc: &mut Consts) -> Result<TokenStream, Error> {
    let f = BigFloat::parse(s, Radix::Dec, usize::MAX, RoundingMode::ToEven, cc);
    if let Some(err) = f.err() {
        return Err(Error::new(
            span,
            format!("failed to parse BigFloat from {}: {}", s, err),
        ));
    }

    let q = if f.inexact() {
        quote!(astro_float::macro_util::check_exponent_range(astro_float::BigFloat::parse(#s, astro_float::Radix::Dec, p_wrk, astro_float::RoundingMode::ToEven, cc), emin, emax))
    } else if let Some((m, n, s, e, inexact)) = f.as_raw_parts() {
        let stoken = if s.is_positive() {
            quote!(astro_float::Sign::Pos)
        } else {
            quote!(astro_float::Sign::Neg)
        };
        quote!(astro_float::macro_util::check_exponent_range(astro_float::BigFloat::from_raw_parts(&[#(#m),*], #n, #stoken, #e, #inexact), emin, emax))
    } else {
        quote!(astro_float::BigFloat::nan())
    };

    Ok(q)
}

pub fn check_arg_num(narg: usize, expr: &ExprCall) -> Result<(), Error> {
    if expr.args.len() != narg {
        return Err(Error::new(
            expr.func.span(),
            if narg == 1 { "expected 1 argument." } else { "expected 2 arguments." },
        ));
    }
    Ok(())
}