Skip to main content

zvariant_derive/
utils.rs

1use proc_macro_crate::{FoundCrate, crate_name};
2use proc_macro2::TokenStream;
3use quote::{format_ident, quote};
4use zvariant_utils::{case, def_attrs};
5
6/// Parses the `crate` attribute value into a path.
7pub fn parse_crate_path(crate_attr: Option<&str>) -> Result<Option<syn::Path>, syn::Error> {
8    crate_attr.map(syn::parse_str).transpose()
9}
10
11/// Returns the path to the zvariant crate.
12///
13/// If a custom crate path is provided via the `crate` attribute, it will be used.
14/// Otherwise, uses `proc-macro-crate` to detect the crate name.
15pub fn zvariant_path(crate_path: Option<&syn::Path>) -> TokenStream {
16    if let Some(path) = crate_path {
17        quote! { ::#path }
18    } else if let Ok(FoundCrate::Name(name)) = crate_name("zvariant") {
19        let ident = format_ident!("{}", name);
20        quote! { ::#ident }
21    } else if let Ok(FoundCrate::Name(name)) = crate_name("zbus") {
22        let ident = format_ident!("{}", name);
23        quote! { ::#ident::zvariant }
24    } else {
25        quote! { ::zvariant }
26    }
27}
28
29pub fn rename_identifier(
30    ident: String,
31    span: proc_macro2::Span,
32    rename_attr: Option<String>,
33    rename_all_attr: Option<&str>,
34) -> Result<String, syn::Error> {
35    if let Some(name) = rename_attr {
36        Ok(name)
37    } else {
38        match rename_all_attr {
39            Some("lowercase") => Ok(ident.to_ascii_lowercase()),
40            Some("UPPERCASE") => Ok(ident.to_ascii_uppercase()),
41            Some("PascalCase") => Ok(case::pascal_or_camel_case(&ident, true)),
42            Some("camelCase") => Ok(case::pascal_or_camel_case(&ident, false)),
43            Some("snake_case") => Ok(case::snake_or_kebab_case(&ident, true)),
44            Some("kebab-case") => Ok(case::snake_or_kebab_case(&ident, false)),
45            None => Ok(ident),
46            Some(other) => Err(syn::Error::new(
47                span,
48                format!("invalid `rename_all` attribute value {other}"),
49            )),
50        }
51    }
52}
53
54def_attrs! {
55    crate zbus, zvariant;
56
57    /// Attributes defined on structures.
58    pub StructAttributes("struct") { signature str, rename_all str, deny_unknown_fields none, crate_path str };
59    /// Attributes defined on fields.
60    pub FieldAttributes("field") { rename str };
61    /// Attributes defined on enumerations.
62    pub EnumAttributes("enum") { signature str, rename_all str, crate_path str };
63    /// Attributes defined on variants.
64    pub VariantAttributes("variant") { rename str };
65}