1use proc_macro_crate::{FoundCrate, crate_name};
2use proc_macro2::TokenStream;
3use quote::{format_ident, quote};
4use zvariant_utils::{case, def_attrs};
5
6pub fn parse_crate_path(crate_attr: Option<&str>) -> Result<Option<syn::Path>, syn::Error> {
8 crate_attr.map(syn::parse_str).transpose()
9}
10
11pub 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 pub StructAttributes("struct") { signature str, rename_all str, deny_unknown_fields none, crate_path str };
59 pub FieldAttributes("field") { rename str };
61 pub EnumAttributes("enum") { signature str, rename_all str, crate_path str };
63 pub VariantAttributes("variant") { rename str };
65}