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