gtk_properties_macro/
lib.rs1#![feature(proc_macro_diagnostic)]
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::parse_macro_input;
5
6mod generate;
7mod parse;
8
9#[proc_macro]
10pub fn properties(tokens: TokenStream) -> TokenStream {
11 let properties = parse_macro_input!(tokens as parse::Properties);
12
13 let mut param_specs: Vec<proc_macro2::TokenStream> = vec![];
14 let mut getters: Vec<proc_macro2::TokenStream> = vec![];
15 let mut setters: Vec<proc_macro2::TokenStream> = vec![];
16
17 for (index, property) in properties.0 .0.into_iter().enumerate() {
18 let id = index + 1;
19 let (param_spec, getter, setter) = generate::property(id, property);
20 param_specs.push(param_spec);
21 if let Some(getter) = getter {
22 getters.push(getter);
23 }
24 if let Some(setter) = setter {
25 setters.push(setter);
26 }
27 }
28
29 TokenStream::from(quote! {
30 fn properties() -> &'static [gtk::glib::ParamSpec] {
31 use once_cell::sync::Lazy;
32 use gtk::glib::*;
33 static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
34 vec![#(#param_specs),*]
35 });
36 PROPERTIES.as_ref()
37 }
38
39 fn property(&self, object: &Self::Type, id: usize, pspec: >k::glib::ParamSpec) -> gtk::glib::Value {
40 use gtk::glib::prelude::*;
41 match id {
42 #(#getters),*
43 _ => unimplemented!()
44 }
45 }
46
47 fn set_property(&self, object: &Self::Type, id: usize, value: >k::glib::Value, pspec: >k::glib::ParamSpec) {
48 use gtk::glib::prelude::*;
49 match id {
50 #(#setters),*
51 _ => unimplemented!()
52 }
53 }
54 })
55}
56
57#[test]
58fn test_expansion() {
59 macrotest::expand("tests/expand/*.rs");
60}