auto_delegate_impl/
attribute.rs

1use proc_macro2::{Ident, Span, TokenStream};
2use quote::ToTokens;
3use syn::Attribute;
4
5pub fn find_to_attribute(attrs: &[Attribute]) -> Option<Attribute> {
6    attrs
7        .iter()
8        .find(|attr| {
9            attr.meta
10                .path()
11                .is_ident("to")
12        })
13        .cloned()
14}
15
16
17pub fn syn_error_not_found_to_attribute() -> syn::Error {
18    syn::Error::new(Span::call_site(), "At least one 'to' attribute must be given.")
19}
20
21
22pub fn syn_error_not_found_trait_names() -> syn::Error {
23    syn::Error::new(Span::call_site(), "At least one trait name must be specified.")
24}
25
26
27pub fn syn_error_not_found_fields() -> syn::Error {
28    syn::Error::new(Span::call_site(), "At least one field must exist.")
29}
30
31
32pub fn trait_names(to_attr: &Attribute) -> Option<Vec<Ident>> {
33    let mut tokens = TokenStream::new();
34    to_attr.to_tokens(&mut tokens);
35
36    let mut trait_names: Vec<Ident> = Vec::new();
37    to_attr
38        .parse_nested_meta(|meta| {
39            meta.path
40                .segments
41                .into_iter()
42                .for_each(|s| trait_names.push(s.ident));
43            Ok(())
44        })
45        .ok()?;
46    if trait_names.is_empty() {
47        None
48    } else {
49        Some(trait_names)
50    }
51}