rustfmt_config_proc_macro/
attrs.rs

1//! This module provides utilities for handling attributes on variants
2//! of `config_type` enum. Currently there are the following attributes
3//! that could appear on the variants of `config_type` enum:
4//!
5//! - `doc_hint`: name-value pair whose value is string literal
6//! - `value`: name-value pair whose value is string literal
7//! - `unstable_variant`: name only
8
9/// Returns the value of the first `doc_hint` attribute in the given slice or
10/// `None` if `doc_hint` attribute is not available.
11pub fn find_doc_hint(attrs: &[syn::Attribute]) -> Option<String> {
12    attrs.iter().filter_map(doc_hint).next()
13}
14
15/// Returns `true` if the given attribute is a `doc_hint` attribute.
16pub fn is_doc_hint(attr: &syn::Attribute) -> bool {
17    is_attr_name_value(attr, "doc_hint")
18}
19
20/// Returns a string literal value if the given attribute is `doc_hint`
21/// attribute or `None` otherwise.
22pub fn doc_hint(attr: &syn::Attribute) -> Option<String> {
23    get_name_value_str_lit(attr, "doc_hint")
24}
25
26/// Returns the value of the first `value` attribute in the given slice or
27/// `None` if `value` attribute is not available.
28pub fn find_config_value(attrs: &[syn::Attribute]) -> Option<String> {
29    attrs.iter().filter_map(config_value).next()
30}
31
32/// Returns `true` if the there is at least one `unstable` attribute in the given slice.
33pub fn any_unstable_variant(attrs: &[syn::Attribute]) -> bool {
34    attrs.iter().any(is_unstable_variant)
35}
36
37/// Returns a string literal value if the given attribute is `value`
38/// attribute or `None` otherwise.
39pub fn config_value(attr: &syn::Attribute) -> Option<String> {
40    get_name_value_str_lit(attr, "value")
41}
42
43/// Returns `true` if the given attribute is a `value` attribute.
44pub fn is_config_value(attr: &syn::Attribute) -> bool {
45    is_attr_name_value(attr, "value")
46}
47
48/// Returns `true` if the given attribute is an `unstable` attribute.
49pub fn is_unstable_variant(attr: &syn::Attribute) -> bool {
50    is_attr_path(attr, "unstable_variant")
51}
52
53fn is_attr_name_value(attr: &syn::Attribute, name: &str) -> bool {
54    match &attr.meta {
55        syn::Meta::NameValue(syn::MetaNameValue { path, .. }) if path.is_ident(name) => true,
56        _ => false,
57    }
58}
59
60fn is_attr_path(attr: &syn::Attribute, name: &str) -> bool {
61    match &attr.meta {
62        syn::Meta::Path(path) if path.is_ident(name) => true,
63        _ => false,
64    }
65}
66
67fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option<String> {
68    match &attr.meta {
69        syn::Meta::NameValue(syn::MetaNameValue {
70            path,
71            value:
72                syn::Expr::Lit(syn::ExprLit {
73                    lit: syn::Lit::Str(lit_str),
74                    ..
75                }),
76            ..
77        }) if path.is_ident(name) => Some(lit_str.value()),
78        _ => None,
79    }
80}