codama_syn_helpers/extensions/
meta_list.rs1use crate::Meta;
2use syn::{punctuated::Punctuated, MetaList};
3
4pub trait MetaListExtension {
5 fn get_self(&self) -> &MetaList;
6
7 fn each(&self, logic: impl FnMut(Meta) -> syn::Result<()>) -> syn::Result<()> {
9 self.parse_metas()?.into_iter().try_for_each(logic)
10 }
11
12 fn parse_metas(&self) -> syn::Result<Vec<Meta>> {
14 self.parse_comma_args::<Meta>()
15 }
16
17 fn parse_comma_args<T: syn::parse::Parse>(&self) -> syn::Result<Vec<T>> {
19 self.get_self()
20 .parse_args_with(Punctuated::<T, syn::Token![,]>::parse_terminated)
21 .map(|metas| metas.into_iter().collect::<Vec<_>>())
22 }
23}
24
25impl MetaListExtension for MetaList {
26 fn get_self(&self) -> &MetaList {
27 self
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::extensions::*;
35
36 #[test]
37 fn each() {
38 let list = syn::parse_str::<MetaList>("foo(one, two, three = 42)").unwrap();
39 let mut items = Vec::new();
40 list.each(|meta| {
41 items.push(meta);
42 Ok(())
43 })
44 .unwrap();
45
46 assert_eq!(items.len(), 3);
47 assert!(items[0].as_path().unwrap().is_strict("one"));
48 assert!(items[1].as_path().unwrap().is_strict("two"));
49 let meta = items[2].as_path_value().unwrap();
50 let expr = meta.value.as_expr().unwrap();
51 assert!(meta.path.is_strict("three"));
52 assert_eq!(expr.as_unsigned_integer::<usize>().unwrap(), 42);
53 }
54}