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}