Skip to content

Commit bffd92a

Browse files
authored
Merge branch 'signal-macro' into main
2 parents d3dc994 + e273192 commit bffd92a

File tree

8 files changed

+673
-4
lines changed

8 files changed

+673
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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_signals(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_signals = false;
25+
26+
for item in items {
27+
if let syn::ImplItem::Fn(method) = item {
28+
let ident = &method.sig.ident;
29+
30+
if ident == "signals" {
31+
has_signals = true;
32+
}
33+
}
34+
}
35+
36+
let glib = crate::utils::crate_ident_new();
37+
38+
let signals = quote!(
39+
fn signals() -> &'static [#glib::subclass::signal::Signal] {
40+
Self::derived_signals()
41+
}
42+
);
43+
44+
let generated = [(!has_signals).then_some(signals)];
45+
46+
Ok(quote!(
47+
#(#attrs)*
48+
impl #generics #trait_path for #self_ty {
49+
#(#items)*
50+
#(#generated)*
51+
}
52+
))
53+
}

glib-macros/src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ mod boxed_derive;
55
mod clone;
66
mod closure;
77
mod derived_properties_attribute;
8+
mod derived_signals_attribute;
89
mod downgrade_derive;
910
mod enum_derive;
1011
mod error_domain_derive;
1112
mod flags_attribute;
1213
mod object_impl_attributes;
1314
mod properties;
1415
mod shared_boxed_derive;
16+
mod signals_attribute;
1517
mod value_delegate_derive;
1618
mod variant_derive;
1719

@@ -1501,6 +1503,32 @@ pub fn derived_properties(_attr: TokenStream, item: TokenStream) -> TokenStream
15011503
.into()
15021504
}
15031505

1506+
/// This macro enables you to implement object signals in a quick way.
1507+
#[proc_macro_attribute]
1508+
pub fn signals(attr: TokenStream, item: TokenStream) -> TokenStream {
1509+
let attr_input = syn::parse_macro_input!(attr as signals_attribute::Args);
1510+
1511+
syn::parse::<syn::ItemImpl>(item)
1512+
.map_err(|_| syn::Error::new(Span::call_site(), signals_attribute::WRONG_PLACE_MSG))
1513+
.and_then(|item_input| signals_attribute::impl_signals(attr_input, item_input))
1514+
.unwrap_or_else(syn::Error::into_compile_error)
1515+
.into()
1516+
}
1517+
1518+
#[proc_macro_attribute]
1519+
pub fn derived_signals(_attr: TokenStream, item: TokenStream) -> TokenStream {
1520+
syn::parse::<syn::ItemImpl>(item)
1521+
.map_err(|_| {
1522+
syn::Error::new(
1523+
Span::call_site(),
1524+
derived_signals_attribute::WRONG_PLACE_MSG,
1525+
)
1526+
})
1527+
.and_then(|input| derived_signals_attribute::impl_derived_signals(&input))
1528+
.unwrap_or_else(syn::Error::into_compile_error)
1529+
.into()
1530+
}
1531+
15041532
/// # Example
15051533
/// ```
15061534
/// use glib::prelude::*;

0 commit comments

Comments
 (0)