educe/common/
int.rs

1use syn::{spanned::Spanned, Expr, Lit, Meta, MetaNameValue, UnOp};
2
3use super::path::path_to_string;
4
5#[inline]
6pub(crate) fn meta_name_value_2_isize(name_value: &MetaNameValue) -> syn::Result<isize> {
7    match &name_value.value {
8        Expr::Lit(lit) => match &lit.lit {
9            Lit::Str(lit) => {
10                return lit
11                    .value()
12                    .parse::<isize>()
13                    .map_err(|error| syn::Error::new(lit.span(), error))
14            },
15            Lit::Int(lit) => return lit.base10_parse(),
16            _ => (),
17        },
18        Expr::Unary(unary) => {
19            if let UnOp::Neg(_) = unary.op {
20                if let Expr::Lit(lit) = unary.expr.as_ref() {
21                    if let Lit::Int(lit) = &lit.lit {
22                        let s = format!("-{}", lit.base10_digits());
23
24                        return s
25                            .parse::<isize>()
26                            .map_err(|error| syn::Error::new(lit.span(), error));
27                    }
28                }
29            }
30        },
31        _ => (),
32    }
33
34    Err(syn::Error::new(
35        name_value.value.span(),
36        format!("expected `{path} = integer`", path = path_to_string(&name_value.path)),
37    ))
38}
39
40#[inline]
41pub(crate) fn meta_2_isize(meta: &Meta) -> syn::Result<isize> {
42    match &meta {
43        Meta::NameValue(name_value) => meta_name_value_2_isize(name_value),
44        Meta::List(list) => {
45            let lit = list.parse_args::<Lit>()?;
46
47            match &lit {
48                Lit::Str(lit) => {
49                    lit.value().parse::<isize>().map_err(|error| syn::Error::new(lit.span(), error))
50                },
51                Lit::Int(lit) => lit.base10_parse(),
52                _ => Err(syn::Error::new(lit.span(), "not an integer")),
53            }
54        },
55        Meta::Path(path) => Err(syn::Error::new(
56            path.span(),
57            format!(
58                "expected `{path} = integer` or `{path}(integer)`",
59                path = path_to_string(path)
60            ),
61        )),
62    }
63}