Skip to content

Commit

Permalink
Add FromMeta for Vec of literals(#265)
Browse files Browse the repository at this point in the history
There is no general implementation for `Vec`, but having the ability to accept a list of literals
and require that they be of the same type is useful enough to merit specific impls.

Co-authored-by: Ted Driggs <ted.driggs@outlook.com>
  • Loading branch information
Ten0 and TedDriggs authored Feb 14, 2024
1 parent db0e40f commit a43190f
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions core/src/from_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,33 @@ macro_rules! from_meta_lit {
}
}
}

impl FromMeta for Vec<$impl_ty> {
fn from_list(items: &[NestedMeta]) -> Result<Self> {
items
.iter()
.map(<$impl_ty as FromMeta>::from_nested_meta)
.collect()
}

fn from_value(value: &syn::Lit) -> Result<Self> {
let expr_array = syn::ExprArray::from_value(value)?;
Self::from_expr(&syn::Expr::Array(expr_array))
}

fn from_expr(expr: &syn::Expr) -> Result<Self> {
match expr {
syn::Expr::Array(expr_array) => expr_array
.elems
.iter()
.map(<$impl_ty as FromMeta>::from_expr)
.collect::<Result<Vec<_>>>(),
syn::Expr::Lit(expr_lit) => Self::from_value(&expr_lit.lit),
syn::Expr::Group(g) => Self::from_expr(&g.expr),
_ => Err(Error::unexpected_expr_type(expr)),
}
}
}
};
}

Expand Down Expand Up @@ -1044,4 +1071,15 @@ mod tests {
vec![0x50, 0xffffffff]
);
}

#[test]
fn test_lit_array() {
fm::<Vec<syn::LitStr>>(quote!(ignore = "[\"Hello World\", \"Test Array\"]"));
fm::<Vec<syn::LitStr>>(quote!(ignore = ["Hello World", "Test Array"]));
fm::<Vec<syn::LitChar>>(quote!(ignore = "['a', 'b', 'c']"));
fm::<Vec<syn::LitBool>>(quote!(ignore = "[true]"));
fm::<Vec<syn::LitStr>>(quote!(ignore = "[]"));
fm::<Vec<syn::LitStr>>(quote!(ignore = []));
fm::<Vec<syn::LitBool>>(quote!(ignore = [true, false]));
}
}

0 comments on commit a43190f

Please sign in to comment.