1use darling::FromDeriveInput;
2use proc_macro::TokenStream;
3
4mod componentized_resource;
5mod labeled_resource;
6mod named_resource;
7
8fn format_attributed(
9 format_str: String,
10 add_name: Option<bool>,
11 add_namespace: Option<bool>,
12 add_component: Option<&syn::Ident>,
13) -> proc_macro2::TokenStream {
14 use quote::quote;
15 match (add_name.unwrap_or(true), add_namespace.unwrap_or(false), add_component) {
16 (true, true, Some(c)) => {
17 quote! {
18 format!(#format_str, name=self.metadata.name.as_ref().unwrap(), namespace=self.metadata.namespace.as_ref().unwrap(), component=<#c as ::staircase::resources::ComponentizedResource>::COMPONENT)
19 }
20 },
21 (true, true, None) => {
22 quote! {
23 format!(#format_str, name=self.metadata.name.as_ref().unwrap(), namespace=self.metadata.namespace.as_ref().unwrap())
24 }
25 },
26 (true, false, Some(c)) => {
27 quote! {
28 format!(#format_str, name=self.metadata.name.as_ref().unwrap(), component=<#c as ::staircase::resources::ComponentizedResource>::COMPONENT)
29 }
30 },
31 (true, false, None) => {
32 quote! {
33 format!(#format_str, name=self.metadata.name.as_ref().unwrap())
34 }
35 },
36 (false, true, Some(c)) => {
37 quote! {
38 format!(#format_str, namespace=self.metadata.namespace.as_ref().unwrap(), component=<#c as ::staircase::resources::ComponentizedResource>::COMPONENT)
39 }
40 },
41 (false, true, None) => {
42 quote! {
43 format!(#format_str, namespace=self.metadata.namespace.as_ref().unwrap())
44 }
45 },
46 (false, false, Some(c)) => {
47 quote! {
48 format!(#format_str, component=<#c as ::staircase::resources::ComponentizedResource>::COMPONENT)
49 }
50 },
51 (false, false, None) => {
52 quote! {
53 format!(#format_str)
54 }
55 },
56 }
57}
58
59#[proc_macro_derive(LabeledResource, attributes(staircase))]
60pub fn derive_labeled_resource(input: TokenStream) -> TokenStream {
61 labeled_resource::derive(proc_macro2::TokenStream::from(input)).into()
62}
63
64#[proc_macro_derive(NamedResource, attributes(staircase))]
65pub fn derive_named_resource(input: TokenStream) -> TokenStream {
66 named_resource::derive(proc_macro2::TokenStream::from(input)).into()
67}
68
69#[proc_macro_derive(ComponentizedResource, attributes(staircase))]
70pub fn derive_componentized_resource(input: TokenStream) -> TokenStream {
71 componentized_resource::derive(proc_macro2::TokenStream::from(input)).into()
72}
73
74#[allow(dead_code)]
75#[derive(FromDeriveInput)]
76#[darling(attributes(staircase))]
77struct StaircaseAttrs {
78 name: Option<String>,
79 label: Option<String>,
80 format_name: Option<bool>,
81 format_namespace: Option<bool>,
82 format_component: Option<bool>,
83 resource: Option<syn::Path>,
84 identifier: Option<syn::Path>,
85 component_type: Option<syn::Path>,
86 component_const: Option<syn::Path>,
87}
88
89#[cfg(test)]
90mod tests {
91 use quote::quote;
92
93 use super::*;
94
95 #[test]
96 fn test_parse_default() {
97 let input = quote! {
98 #[staircase(label = "{label}", name = "{name}")]
99 struct FooSpec;
100 };
101 let input = syn::parse2(input).unwrap();
102 let attrs = StaircaseAttrs::from_derive_input(&input).unwrap();
103 assert_eq!(attrs.label, Some("{label}".to_string()));
104 assert_eq!(attrs.name, Some("{name}".to_string()));
105 }
106}