1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use proc_macro2::TokenStream; |
4 | use proc_macro_error::abort_call_site; |
5 | use quote::quote; |
6 | |
7 | pub const WRONG_PLACE_MSG: &str = |
8 | "This macro should be used on `impl` block for `glib::ObjectImpl` trait" ; |
9 | |
10 | pub fn impl_derived_properties(input: &syn::ItemImpl) -> TokenStream { |
11 | let syn::ItemImpl { |
12 | attrs, |
13 | generics, |
14 | trait_, |
15 | self_ty, |
16 | items, |
17 | .. |
18 | } = input; |
19 | |
20 | let trait_path = match &trait_ { |
21 | Some(path) => &path.1, |
22 | None => abort_call_site!(WRONG_PLACE_MSG), |
23 | }; |
24 | |
25 | let mut has_property = false; |
26 | let mut has_properties = false; |
27 | let mut has_set_property = false; |
28 | |
29 | for item in items { |
30 | if let syn::ImplItem::Fn(method) = item { |
31 | let ident = &method.sig.ident; |
32 | |
33 | if ident == "properties" { |
34 | has_properties = true; |
35 | } else if ident == "set_property" { |
36 | has_set_property = true; |
37 | } else if ident == "property" { |
38 | has_property = true; |
39 | } |
40 | } |
41 | } |
42 | |
43 | let crate_ident = crate::utils::crate_ident_new(); |
44 | |
45 | let properties = quote!( |
46 | fn properties() -> &'static [#crate_ident::ParamSpec] { |
47 | Self::derived_properties() |
48 | } |
49 | ); |
50 | |
51 | let set_property = quote!( |
52 | fn set_property(&self, id: usize, value: &#crate_ident::Value, pspec: &#crate_ident::ParamSpec) { |
53 | Self::derived_set_property(self, id, value, pspec) |
54 | } |
55 | ); |
56 | |
57 | let property = quote!( |
58 | fn property(&self, id: usize, pspec: &#crate_ident::ParamSpec) -> #crate_ident::Value { |
59 | Self::derived_property(self, id, pspec) |
60 | } |
61 | ); |
62 | |
63 | let generated = [ |
64 | (!has_properties).then_some(properties), |
65 | (!has_set_property).then_some(set_property), |
66 | (!has_property).then_some(property), |
67 | ]; |
68 | |
69 | quote!( |
70 | #(#attrs)* |
71 | impl #generics #trait_path for #self_ty { |
72 | #(#items)* |
73 | #(#generated)* |
74 | } |
75 | ) |
76 | } |
77 | |