serde_derive/
deprecated.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3
4pub fn allow_deprecated(input: &syn::DeriveInput) -> Option<TokenStream> {
5    if should_allow_deprecated(input) {
6        Some(quote! { #[allow(deprecated)] })
7    } else {
8        None
9    }
10}
11
12/// Determine if an `#[allow(deprecated)]` should be added to the derived impl.
13///
14/// This should happen if the derive input or an enum variant it contains has
15/// one of:
16///   - `#[deprecated]`
17///   - `#[allow(deprecated)]`
18fn should_allow_deprecated(input: &syn::DeriveInput) -> bool {
19    if contains_deprecated(&input.attrs) {
20        return true;
21    }
22    if let syn::Data::Enum(data_enum) = &input.data {
23        for variant in &data_enum.variants {
24            if contains_deprecated(&variant.attrs) {
25                return true;
26            }
27        }
28    }
29    false
30}
31
32/// Check whether the given attributes contains one of:
33///   - `#[deprecated]`
34///   - `#[allow(deprecated)]`
35fn contains_deprecated(attrs: &[syn::Attribute]) -> bool {
36    for attr in attrs {
37        if attr.path().is_ident("deprecated") {
38            return true;
39        }
40        if let syn::Meta::List(meta_list) = &attr.meta {
41            if meta_list.path.is_ident("allow") {
42                let mut allow_deprecated = false;
43                let _ = meta_list.parse_nested_meta(|meta| {
44                    if meta.path.is_ident("deprecated") {
45                        allow_deprecated = true;
46                    }
47                    Ok(())
48                });
49                if allow_deprecated {
50                    return true;
51                }
52            }
53        }
54    }
55    false
56}