1// Take a look at the license at the top of the repository in the LICENSE file.
2
3mod boxed_derive;
4mod clone;
5mod closure;
6mod derived_properties_attribute;
7mod downgrade_derive;
8mod enum_derive;
9mod error_domain_derive;
10mod flags_attribute;
11mod object_interface_attribute;
12mod object_subclass_attribute;
13mod properties;
14mod shared_boxed_derive;
15mod value_delegate_derive;
16mod variant_derive;
17
18mod utils;
19
20use flags_attribute::AttrInput;
21use proc_macro::TokenStream;
22use proc_macro_error::proc_macro_error;
23use syn::{parse_macro_input, DeriveInput};
24use utils::{parse_nested_meta_items_from_stream, NestedMetaItem};
25
26/// Macro for passing variables as strong or weak references into a closure.
27///
28/// This macro can be useful in combination with closures, e.g. signal handlers, to reduce the
29/// boilerplate required for passing strong or weak references into the closure. It will
30/// automatically create the new reference and pass it with the same name into the closure.
31///
32/// If upgrading the weak reference to a strong reference inside the closure is failing, the
33/// closure is immediately returning an optional default return value. If none is provided, `()` is
34/// returned.
35///
36/// **⚠️ IMPORTANT ⚠️**
37///
38/// `glib` needs to be in scope, so unless it's one of the direct crate dependencies, you need to
39/// import it because `clone!` is using it. For example:
40///
41/// ```rust,ignore
42/// use gtk::glib;
43/// ```
44///
45/// ### Debugging
46///
47/// In case something goes wrong inside the `clone!` macro, we use the [`g_debug`] macro. Meaning
48/// that if you want to see these debug messages, you'll have to set the `G_MESSAGES_DEBUG`
49/// environment variable when running your code (either in the code directly or when running the
50/// binary) to either "all" or [`CLONE_MACRO_LOG_DOMAIN`]:
51///
52/// [`g_debug`]: ../glib/macro.g_debug.html
53/// [`CLONE_MACRO_LOG_DOMAIN`]: ../glib/constant.CLONE_MACRO_LOG_DOMAIN.html
54///
55/// ```rust,ignore
56/// use glib::CLONE_MACRO_LOG_DOMAIN;
57///
58/// std::env::set_var("G_MESSAGES_DEBUG", CLONE_MACRO_LOG_DOMAIN);
59/// std::env::set_var("G_MESSAGES_DEBUG", "all");
60/// ```
61///
62/// Or:
63///
64/// ```bash
65/// $ G_MESSAGES_DEBUG=all ./binary
66/// ```
67///
68/// ### Passing a strong reference
69///
70/// ```
71/// use glib;
72/// use glib_macros::clone;
73/// use std::rc::Rc;
74///
75/// let v = Rc::new(1);
76/// let closure = clone!(@strong v => move |x| {
77/// println!("v: {}, x: {}", v, x);
78/// });
79///
80/// closure(2);
81/// ```
82///
83/// ### Passing a weak reference
84///
85/// ```
86/// use glib;
87/// use glib_macros::clone;
88/// use std::rc::Rc;
89///
90/// let u = Rc::new(2);
91/// let closure = clone!(@weak u => move |x| {
92/// println!("u: {}, x: {}", u, x);
93/// });
94///
95/// closure(3);
96/// ```
97///
98/// #### Allowing a nullable weak reference
99///
100/// In some cases, even if the weak references can't be retrieved, you might want to still have
101/// your closure called. In this case, you need to use `@weak-allow-none`:
102///
103/// ```
104/// use glib;
105/// use glib_macros::clone;
106/// use std::rc::Rc;
107///
108/// let closure = {
109/// // This `Rc` won't be available in the closure because it's dropped at the end of the
110/// // current block
111/// let u = Rc::new(2);
112/// clone!(@weak-allow-none u => @default-return false, move |x| {
113/// // We need to use a Debug print for `u` because it'll be an `Option`.
114/// println!("u: {:?}, x: {}", u, x);
115/// true
116/// })
117/// };
118///
119/// assert_eq!(closure(3), true);
120/// ```
121///
122/// ### Creating owned values from references (`ToOwned`)
123///
124/// ```
125/// use glib;
126/// use glib_macros::clone;
127///
128/// let v = "123";
129/// let closure = clone!(@to-owned v => move |x| {
130/// // v is passed as `String` here
131/// println!("v: {}, x: {}", v, x);
132/// });
133///
134/// closure(2);
135/// ```
136///
137/// ### Renaming variables
138///
139/// ```
140/// use glib;
141/// use glib_macros::clone;
142/// use std::rc::Rc;
143///
144/// let v = Rc::new(1);
145/// let u = Rc::new(2);
146/// let closure = clone!(@strong v as y, @weak u => move |x| {
147/// println!("v as y: {}, u: {}, x: {}", y, u, x);
148/// });
149///
150/// closure(3);
151/// ```
152///
153/// ### Providing a default return value if upgrading a weak reference fails
154///
155/// You can do it in two different ways:
156///
157/// Either by providing the value yourself using `@default-return`:
158///
159/// ```
160/// use glib;
161/// use glib_macros::clone;
162/// use std::rc::Rc;
163///
164/// let v = Rc::new(1);
165/// let closure = clone!(@weak v => @default-return false, move |x| {
166/// println!("v: {}, x: {}", v, x);
167/// true
168/// });
169///
170/// // Drop value so that the weak reference can't be upgraded.
171/// drop(v);
172///
173/// assert_eq!(closure(2), false);
174/// ```
175///
176/// Or by using `@default-panic` (if the value fails to get upgraded, it'll panic):
177///
178/// ```should_panic
179/// # use glib;
180/// # use glib_macros::clone;
181/// # use std::rc::Rc;
182/// # let v = Rc::new(1);
183/// let closure = clone!(@weak v => @default-panic, move |x| {
184/// println!("v: {}, x: {}", v, x);
185/// true
186/// });
187/// # drop(v);
188/// # assert_eq!(closure(2), false);
189/// ```
190///
191/// ### Errors
192///
193/// Here is a list of errors you might encounter:
194///
195/// **Missing `@weak` or `@strong`**:
196///
197/// ```compile_fail
198/// # use glib;
199/// # use glib_macros::clone;
200/// # use std::rc::Rc;
201/// let v = Rc::new(1);
202///
203/// let closure = clone!(v => move |x| println!("v: {}, x: {}", v, x));
204/// # drop(v);
205/// # closure(2);
206/// ```
207///
208/// **Passing `self` as an argument**:
209///
210/// ```compile_fail
211/// # use glib;
212/// # use glib_macros::clone;
213/// # use std::rc::Rc;
214/// #[derive(Debug)]
215/// struct Foo;
216///
217/// impl Foo {
218/// fn foo(&self) {
219/// let closure = clone!(@strong self => move |x| {
220/// println!("self: {:?}", self);
221/// });
222/// # closure(2);
223/// }
224/// }
225/// ```
226///
227/// If you want to use `self` directly, you'll need to rename it:
228///
229/// ```
230/// # use glib;
231/// # use glib_macros::clone;
232/// # use std::rc::Rc;
233/// #[derive(Debug)]
234/// struct Foo;
235///
236/// impl Foo {
237/// fn foo(&self) {
238/// let closure = clone!(@strong self as this => move |x| {
239/// println!("self: {:?}", this);
240/// });
241/// # closure(2);
242/// }
243/// }
244/// ```
245///
246/// **Passing fields directly**
247///
248/// ```compile_fail
249/// # use glib;
250/// # use glib_macros::clone;
251/// # use std::rc::Rc;
252/// #[derive(Debug)]
253/// struct Foo {
254/// v: Rc<usize>,
255/// }
256///
257/// impl Foo {
258/// fn foo(&self) {
259/// let closure = clone!(@strong self.v => move |x| {
260/// println!("self.v: {:?}", v);
261/// });
262/// # closure(2);
263/// }
264/// }
265/// ```
266///
267/// You can do it by renaming it:
268///
269/// ```
270/// # use glib;
271/// # use glib_macros::clone;
272/// # use std::rc::Rc;
273/// # struct Foo {
274/// # v: Rc<usize>,
275/// # }
276/// impl Foo {
277/// fn foo(&self) {
278/// let closure = clone!(@strong self.v as v => move |x| {
279/// println!("self.v: {}", v);
280/// });
281/// # closure(2);
282/// }
283/// }
284/// ```
285#[proc_macro]
286#[proc_macro_error]
287pub fn clone(item: TokenStream) -> TokenStream {
288 clone::clone_inner(item)
289}
290
291/// Macro for creating a [`Closure`] object. This is a wrapper around [`Closure::new`] that
292/// automatically type checks its arguments at run-time.
293///
294/// A `Closure` takes [`Value`] objects as inputs and output. This macro will automatically convert
295/// the inputs to Rust types when invoking its callback, and then will convert the output back to a
296/// `Value`. All inputs must implement the [`FromValue`] trait, and outputs must either implement
297/// the [`ToValue`] trait or be the unit type `()`. Type-checking of inputs is done at run-time; if
298/// incorrect types are passed via [`Closure::invoke`] then the closure will panic. Note that when
299/// passing input types derived from [`Object`] or [`Interface`], you must take care to upcast to
300/// the exact object or interface type that is being received.
301///
302/// Similarly to [`clone!`](crate::clone!), this macro can be useful in combination with signal
303/// handlers to reduce boilerplate when passing references. Unique to `Closure` objects is the
304/// ability to watch an object using a the `@watch` directive. Only an [`Object`] value can be
305/// passed to `@watch`, and only one object can be watched per closure. When an object is watched,
306/// a weak reference to the object is held in the closure. When the object is destroyed, the
307/// closure will become invalidated: all signal handlers connected to the closure will become
308/// disconnected, and any calls to [`Closure::invoke`] on the closure will be silently ignored.
309/// Internally, this is accomplished using [`Object::watch_closure`] on the watched object.
310///
311/// The `@weak-allow-none` and `@strong` captures are also supported and behave the same as in
312/// [`clone!`](crate::clone!), as is aliasing captures with the `as` keyword. Notably, these
313/// captures are able to reference `Rc` and `Arc` values in addition to `Object` values.
314///
315/// [`Closure`]: ../glib/closure/struct.Closure.html
316/// [`Closure::new`]: ../glib/closure/struct.Closure.html#method.new
317/// [`Closure::new_local`]: ../glib/closure/struct.Closure.html#method.new_local
318/// [`Closure::invoke`]: ../glib/closure/struct.Closure.html#method.invoke
319/// [`Value`]: ../glib/value/struct.Value.html
320/// [`FromValue`]: ../glib/value/trait.FromValue.html
321/// [`ToValue`]: ../glib/value/trait.ToValue.html
322/// [`Interface`]: ../glib/object/struct.Interface.html
323/// [`Object`]: ../glib/object/struct.Object.html
324/// [`Object::watch_closure`]: ../glib/object/trait.ObjectExt.html#tymethod.watch_closure
325/// **⚠️ IMPORTANT ⚠️**
326///
327/// `glib` needs to be in scope, so unless it's one of the direct crate dependencies, you need to
328/// import it because `closure!` is using it. For example:
329///
330/// ```rust,ignore
331/// use gtk::glib;
332/// ```
333///
334/// ### Using as a closure object
335///
336/// ```
337/// use glib_macros::closure;
338///
339/// let concat_str = closure!(|s: &str| s.to_owned() + " World");
340/// let result = concat_str.invoke::<String>(&[&"Hello"]);
341/// assert_eq!(result, "Hello World");
342/// ```
343///
344/// ### Connecting to a signal
345///
346/// For wrapping closures that can't be sent across threads, the
347/// [`closure_local!`](crate::closure_local!) macro can be used. It has the same syntax as
348/// `closure!`, but instead uses [`Closure::new_local`] internally.
349///
350/// ```
351/// use glib;
352/// use glib::prelude::*;
353/// use glib_macros::closure_local;
354///
355/// let obj = glib::Object::new::<glib::Object>();
356/// obj.connect_closure(
357/// "notify", false,
358/// closure_local!(|_obj: glib::Object, pspec: glib::ParamSpec| {
359/// println!("property notify: {}", pspec.name());
360/// }));
361/// ```
362///
363/// ### Object Watching
364///
365/// ```
366/// use glib;
367/// use glib::prelude::*;
368/// use glib_macros::closure_local;
369///
370/// let closure = {
371/// let obj = glib::Object::new::<glib::Object>();
372/// let closure = closure_local!(@watch obj => move || {
373/// obj.type_().name()
374/// });
375/// assert_eq!(closure.invoke::<String>(&[]), "GObject");
376/// closure
377/// };
378/// // `obj` is dropped, closure invalidated so it always does nothing and returns None
379/// closure.invoke::<()>(&[]);
380/// ```
381///
382/// `@watch` has special behavior when connected to a signal:
383///
384/// ```
385/// use glib;
386/// use glib::prelude::*;
387/// use glib_macros::closure_local;
388///
389/// let obj = glib::Object::new::<glib::Object>();
390/// {
391/// let other = glib::Object::new::<glib::Object>();
392/// obj.connect_closure(
393/// "notify", false,
394/// closure_local!(@watch other as b => move |a: glib::Object, pspec: glib::ParamSpec| {
395/// let value = a.property_value(pspec.name());
396/// b.set_property(pspec.name(), &value);
397/// }));
398/// // The signal handler will disconnect automatically at the end of this
399/// // block when `other` is dropped.
400/// }
401/// ```
402///
403/// ### Weak and Strong References
404///
405/// ```
406/// use glib;
407/// use glib::prelude::*;
408/// use glib_macros::closure;
409/// use std::sync::Arc;
410///
411/// let closure = {
412/// let a = Arc::new(String::from("Hello"));
413/// let b = Arc::new(String::from("World"));
414/// let c = "!";
415/// let closure = closure!(@strong a, @weak-allow-none b, @to-owned c => move || {
416/// // `a` is Arc<String>, `b` is Option<Arc<String>>, `c` is a `String`
417/// format!("{} {}{}", a, b.as_ref().map(|b| b.as_str()).unwrap_or_else(|| "Moon"), c)
418/// });
419/// assert_eq!(closure.invoke::<String>(&[]), "Hello World!");
420/// closure
421/// };
422/// // `a`, `c` still kept alive, `b` is dropped
423/// assert_eq!(closure.invoke::<String>(&[]), "Hello Moon!");
424/// ```
425#[proc_macro]
426#[proc_macro_error]
427pub fn closure(item: TokenStream) -> TokenStream {
428 closure::closure_inner(input:item, constructor:"new")
429}
430
431/// The same as [`closure!`](crate::closure!) but uses [`Closure::new_local`] as a constructor.
432/// This is useful for closures which can't be sent across threads. See the documentation of
433/// [`closure!`](crate::closure!) for details.
434///
435/// [`Closure::new_local`]: ../glib/closure/struct.Closure.html#method.new_local
436#[proc_macro]
437#[proc_macro_error]
438pub fn closure_local(item: TokenStream) -> TokenStream {
439 closure::closure_inner(input:item, constructor:"new_local")
440}
441
442/// Derive macro for register a rust enum in the glib type system and derive the
443/// the [`glib::Value`] traits.
444///
445/// # Example
446///
447/// ```
448/// use glib::prelude::*;
449/// use glib::subclass::prelude::*;
450///
451/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
452/// #[enum_type(name = "MyEnum")]
453/// enum MyEnum {
454/// Val,
455/// #[enum_value(name = "My Val")]
456/// ValWithCustomName,
457/// #[enum_value(name = "My Other Val", nick = "other")]
458/// ValWithCustomNameAndNick,
459/// }
460/// ```
461///
462/// [`glib::Value`]: ../glib/value/struct.Value.html
463#[proc_macro_derive(Enum, attributes(enum_type, enum_value))]
464#[proc_macro_error]
465pub fn enum_derive(input: TokenStream) -> TokenStream {
466 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
467 let gen: TokenStream = enum_derive::impl_enum(&input);
468 gen.into()
469}
470
471/// Attribute macro for defining flags using the `bitflags` crate.
472/// This macro will also define a `GFlags::type_` function and
473/// the [`glib::Value`] traits.
474///
475/// The expected `GType` name has to be passed as macro attribute.
476/// The name and nick of each flag can also be optionally defined.
477/// Default name is the flag identifier in CamelCase and default nick
478/// is the identifier in kebab-case.
479/// Combined flags should not be registered with the `GType` system
480/// and so needs to be tagged with the `#[flags_value(skip)]` attribute.
481///
482/// # Example
483///
484/// ```
485/// use glib::prelude::*;
486/// use glib::subclass::prelude::*;
487///
488/// #[glib::flags(name = "MyFlags")]
489/// enum MyFlags {
490/// #[flags_value(name = "Flag A", nick = "nick-a")]
491/// A = 0b00000001,
492/// #[flags_value(name = "Flag B")]
493/// B = 0b00000010,
494/// #[flags_value(skip)]
495/// AB = Self::A.bits() | Self::B.bits(),
496/// C = 0b00000100,
497/// }
498/// ```
499///
500/// [`glib::Value`]: ../glib/value/struct.Value.html
501#[proc_macro_attribute]
502#[proc_macro_error]
503pub fn flags(attr: TokenStream, item: TokenStream) -> TokenStream {
504 let mut name: NestedMetaItem = NestedMetaItemNestedMetaItem::<syn::LitStr>::new(name:"name")
505 .required()
506 .value_required();
507
508 if let Err(e: Error) = parse_nested_meta_items_from_stream(input:attr.into(), &mut [&mut name]) {
509 return e.to_compile_error().into();
510 }
511
512 let attr_meta: AttrInput = AttrInput {
513 enum_name: name.value.unwrap(),
514 };
515 let input: DeriveInput = parse_macro_input!(item as DeriveInput);
516 let gen: TokenStream = flags_attribute::impl_flags(attrs:attr_meta, &input);
517 gen.into()
518}
519
520/// Derive macro for defining a GLib error domain and its associated
521/// [`ErrorDomain`] trait.
522///
523/// # Example
524///
525/// ```
526/// use glib::prelude::*;
527/// use glib::subclass::prelude::*;
528///
529/// #[derive(Debug, Copy, Clone, glib::ErrorDomain)]
530/// #[error_domain(name = "ex-foo")]
531/// enum Foo {
532/// Blah,
533/// Baaz,
534/// }
535/// ```
536///
537/// [`ErrorDomain`]: ../glib/error/trait.ErrorDomain.html
538#[proc_macro_derive(ErrorDomain, attributes(error_domain))]
539#[proc_macro_error]
540pub fn error_domain_derive(input: TokenStream) -> TokenStream {
541 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
542 let gen: TokenStream = error_domain_derive::impl_error_domain(&input);
543 gen.into()
544}
545
546/// Derive macro for defining a [`BoxedType`]`::type_` function and
547/// the [`glib::Value`] traits. Optionally, the type can be marked as
548/// `nullable` to get an implemention of `glib::value::ToValueOptional`.
549///
550/// # Example
551///
552/// ```
553/// use glib::prelude::*;
554/// use glib::subclass::prelude::*;
555///
556/// #[derive(Clone, Debug, PartialEq, Eq, glib::Boxed)]
557/// #[boxed_type(name = "MyBoxed")]
558/// struct MyBoxed(String);
559///
560/// #[derive(Clone, Debug, PartialEq, Eq, glib::Boxed)]
561/// #[boxed_type(name = "MyNullableBoxed", nullable)]
562/// struct MyNullableBoxed(String);
563/// ```
564///
565/// [`BoxedType`]: ../glib/subclass/boxed/trait.BoxedType.html
566/// [`glib::Value`]: ../glib/value/struct.Value.html
567#[proc_macro_derive(Boxed, attributes(boxed_type))]
568#[proc_macro_error]
569pub fn boxed_derive(input: TokenStream) -> TokenStream {
570 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
571 let gen: TokenStream = boxed_derive::impl_boxed(&input);
572 gen.into()
573}
574
575/// Derive macro for defining a [`SharedType`]`::get_type` function and
576/// the [`glib::Value`] traits. Optionally, the type can be marked as
577/// `nullable` to get an implemention of `glib::value::ToValueOptional`.
578///
579/// # Example
580///
581/// ```
582/// use glib::prelude::*;
583/// use glib::subclass::prelude::*;
584///
585/// #[derive(Clone, Debug, PartialEq, Eq)]
586/// struct MySharedInner {
587/// foo: String,
588/// }
589///
590/// #[derive(Clone, Debug, PartialEq, Eq, glib::SharedBoxed)]
591/// #[shared_boxed_type(name = "MySharedBoxed")]
592/// struct MySharedBoxed(std::sync::Arc<MySharedInner>);
593///
594/// #[derive(Clone, Debug, PartialEq, Eq, glib::SharedBoxed)]
595/// #[shared_boxed_type(name = "MyNullableSharedBoxed", nullable)]
596/// struct MyNullableSharedBoxed(std::sync::Arc<MySharedInner>);
597/// ```
598///
599/// [`SharedType`]: ../glib/subclass/shared/trait.SharedType.html
600/// [`glib::Value`]: ../glib/value/struct.Value.html
601#[proc_macro_derive(SharedBoxed, attributes(shared_boxed_type))]
602#[proc_macro_error]
603pub fn shared_boxed_derive(input: TokenStream) -> TokenStream {
604 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
605 let gen: TokenStream = shared_boxed_derive::impl_shared_boxed(&input);
606 gen.into()
607}
608
609/// Macro for boilerplate of [`ObjectSubclass`] implementations.
610///
611/// This adds implementations for the `type_data()` and `type_()` methods,
612/// which should probably never be defined differently.
613///
614/// It provides default values for the `Instance`, `Class`, and `Interfaces`
615/// type parameters. If these are present, the macro will use the provided value
616/// instead of the default.
617///
618/// Usually the defaults for `Instance` and `Class` will work. `Interfaces` is
619/// necessary for types that implement interfaces.
620///
621/// ```ignore
622/// type Instance = glib::subclass::basic::InstanceStruct<Self>;
623/// type Class = glib::subclass::basic::ClassStruct<Self>;
624/// type Interfaces = ();
625/// ```
626///
627/// If no `new()` or `with_class()` method is provide, the macro adds a `new()`
628/// implementation calling `Default::default()`. So the type needs to implement
629/// `Default`, or this should be overridden.
630///
631/// ```ignore
632/// fn new() -> Self {
633/// Default::default()
634/// }
635/// ```
636///
637/// [`ObjectSubclass`]: ../glib/subclass/types/trait.ObjectSubclass.html
638#[proc_macro_attribute]
639#[proc_macro_error]
640pub fn object_subclass(_attr: TokenStream, item: TokenStream) -> TokenStream {
641 use proc_macro_error::abort_call_site;
642 match syn::parse::<syn::ItemImpl>(tokens:item) {
643 Ok(input: ItemImpl) => object_subclass_attribute::impl_object_subclass(&input).into(),
644 Err(_) => abort_call_site!(object_subclass_attribute::WRONG_PLACE_MSG),
645 }
646}
647
648/// Macro for boilerplate of [`ObjectInterface`] implementations.
649///
650/// This adds implementations for the `get_type()` method, which should probably never be defined
651/// differently.
652///
653/// It provides default values for the `Prerequisites` type parameter. If this present, the macro
654/// will use the provided value instead of the default.
655///
656/// `Prerequisites` is interfaces for types that require a specific base class or interfaces.
657///
658/// ```ignore
659/// type Prerequisites = ();
660/// ```
661///
662/// [`ObjectInterface`]: ../glib/subclass/interface/trait.ObjectInterface.html
663#[proc_macro_attribute]
664#[proc_macro_error]
665pub fn object_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
666 use proc_macro_error::abort_call_site;
667 match syn::parse::<syn::ItemImpl>(tokens:item) {
668 Ok(input: ItemImpl) => object_interface_attribute::impl_object_interface(&input).into(),
669 Err(_) => abort_call_site!(object_interface_attribute::WRONG_PLACE_MSG),
670 }
671}
672
673/// Macro for deriving implementations of [`glib::clone::Downgrade`] and
674/// [`glib::clone::Upgrade`] traits and a weak type.
675///
676/// # Examples
677///
678/// ## New Type Idiom
679///
680/// ```rust,ignore
681/// #[derive(glib::Downgrade)]
682/// pub struct FancyLabel(gtk::Label);
683///
684/// impl FancyLabel {
685/// pub fn new(label: &str) -> Self {
686/// Self(gtk::LabelBuilder::new().label(label).build())
687/// }
688///
689/// pub fn flip(&self) {
690/// self.0.set_angle(180.0 - self.0.angle());
691/// }
692/// }
693///
694/// let fancy_label = FancyLabel::new("Look at me!");
695/// let button = gtk::ButtonBuilder::new().label("Click me!").build();
696/// button.connect_clicked(clone!(@weak fancy_label => move || fancy_label.flip()));
697/// ```
698///
699/// ## Generic New Type
700///
701/// ```rust,ignore
702/// #[derive(glib::Downgrade)]
703/// pub struct TypedEntry<T>(gtk::Entry, std::marker::PhantomData<T>);
704///
705/// impl<T: ToString + FromStr> for TypedEntry<T> {
706/// // ...
707/// }
708/// ```
709///
710/// ## Structures and Enums
711///
712/// ```rust,ignore
713/// #[derive(Clone, glib::Downgrade)]
714/// pub struct ControlButtons {
715/// pub up: gtk::Button,
716/// pub down: gtk::Button,
717/// pub left: gtk::Button,
718/// pub right: gtk::Button,
719/// }
720///
721/// #[derive(Clone, glib::Downgrade)]
722/// pub enum DirectionButton {
723/// Left(gtk::Button),
724/// Right(gtk::Button),
725/// Up(gtk::Button),
726/// Down(gtk::Button),
727/// }
728/// ```
729///
730/// [`glib::clone::Downgrade`]: ../glib/clone/trait.Downgrade.html
731/// [`glib::clone::Upgrade`]: ../glib/clone/trait.Upgrade.html
732#[proc_macro_derive(Downgrade)]
733pub fn downgrade(input: TokenStream) -> TokenStream {
734 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
735 downgrade_derive::impl_downgrade(input)
736}
737
738/// Derive macro for serializing/deserializing custom structs/enums as [`glib::Variant`]s.
739///
740/// # Example
741///
742/// ```
743/// use glib::prelude::*;
744///
745/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
746/// struct Foo {
747/// some_string: String,
748/// some_int: i32,
749/// }
750///
751/// let v = Foo { some_string: String::from("bar"), some_int: 1 };
752/// let var = v.to_variant();
753/// assert_eq!(var.get::<Foo>(), Some(v));
754/// ```
755///
756/// When storing `Vec`s of fixed size types it is a good idea to wrap these in
757/// `glib::FixedSizeVariantArray` as serialization/deserialization will be more efficient.
758///
759/// # Example
760///
761/// ```
762/// use glib::prelude::*;
763///
764/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
765/// struct Foo {
766/// some_vec: glib::FixedSizeVariantArray<Vec<u32>, u32>,
767/// some_int: i32,
768/// }
769///
770/// let v = Foo { some_vec: vec![1u32, 2u32].into(), some_int: 1 };
771/// let var = v.to_variant();
772/// assert_eq!(var.get::<Foo>(), Some(v));
773/// ```
774///
775/// Enums are serialized as a tuple `(sv)` with the first value as a [kebab case] string for the
776/// enum variant, or just `s` if this is a C-style enum. Some additional attributes are supported
777/// for enums:
778/// - `#[variant_enum(repr)]` to serialize the enum variant as an integer type instead of `s`. The
779/// `#[repr]` attribute must also be specified on the enum with a sized integer type, and the type
780/// must implement `Copy`.
781/// - `#[variant_enum(enum)]` uses [`EnumClass`] to serialize/deserialize as nicks. Meant for use
782/// with [`glib::Enum`](Enum).
783/// - `#[variant_enum(flags)]` uses [`FlagsClass`] to serialize/deserialize as nicks. Meant for use
784/// with [`glib::flags`](macro@flags).
785/// - `#[variant_enum(enum, repr)]` serializes as `i32`. Meant for use with [`glib::Enum`](Enum).
786/// The type must also implement `Copy`.
787/// - `#[variant_enum(flags, repr)]` serializes as `u32`. Meant for use with
788/// [`glib::flags`](macro@flags).
789///
790/// # Example
791///
792/// ```
793/// use glib::prelude::*;
794///
795/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
796/// enum Foo {
797/// MyA,
798/// MyB(i32),
799/// MyC { some_int: u32, some_string: String }
800/// }
801///
802/// let v = Foo::MyC { some_int: 1, some_string: String::from("bar") };
803/// let var = v.to_variant();
804/// assert_eq!(var.child_value(0).str(), Some("my-c"));
805/// assert_eq!(var.get::<Foo>(), Some(v));
806///
807/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Variant)]
808/// #[variant_enum(repr)]
809/// #[repr(u8)]
810/// enum Bar {
811/// A,
812/// B = 3,
813/// C = 7
814/// }
815///
816/// let v = Bar::B;
817/// let var = v.to_variant();
818/// assert_eq!(var.get::<u8>(), Some(3));
819/// assert_eq!(var.get::<Bar>(), Some(v));
820///
821/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum, glib::Variant)]
822/// #[variant_enum(enum)]
823/// #[enum_type(name = "MyEnum")]
824/// enum MyEnum {
825/// Val,
826/// #[enum_value(name = "My Val")]
827/// ValWithCustomName,
828/// #[enum_value(name = "My Other Val", nick = "other")]
829/// ValWithCustomNameAndNick,
830/// }
831///
832/// let v = MyEnum::ValWithCustomNameAndNick;
833/// let var = v.to_variant();
834/// assert_eq!(var.str(), Some("other"));
835/// assert_eq!(var.get::<MyEnum>(), Some(v));
836/// ```
837///
838/// [`glib::Variant`]: ../glib/variant/struct.Variant.html
839/// [`EnumClass`]: ../glib/struct.EnumClass.html
840/// [`FlagsClass`]: ../glib/struct.FlagsClass.html
841/// [kebab case]: https://docs.rs/heck/0.4.0/heck/trait.ToKebabCase.html
842#[proc_macro_derive(Variant, attributes(variant_enum))]
843#[proc_macro_error]
844pub fn variant_derive(input: TokenStream) -> TokenStream {
845 let input: DeriveInput = parse_macro_input!(input as DeriveInput);
846 variant_derive::impl_variant(input)
847}
848#[proc_macro]
849pub fn cstr_bytes(item: TokenStream) -> TokenStream {
850 syn::parse::Parser::parse2(
851 |stream: syn::parse::ParseStream<'_>| {
852 let literal = stream.parse::<syn::LitStr>()?;
853 stream.parse::<syn::parse::Nothing>()?;
854 let bytes = std::ffi::CString::new(literal.value())
855 .map_err(|e| syn::Error::new_spanned(&literal, format!("{e}")))?
856 .into_bytes_with_nul();
857 let bytes = proc_macro2::Literal::byte_string(&bytes);
858 Ok(quote::quote! { #bytes }.into())
859 },
860 item.into(),
861 )
862 .unwrap_or_else(|e: Error| e.into_compile_error().into())
863}
864
865/// This macro enables you to derive object properties in a quick way.
866///
867/// # Supported `#[property]` attributes
868/// | Attribute | Description | Default | Example |
869/// | --- | --- | --- | --- |
870/// | `name = "literal"` | The name of the property | field ident where `_` (leading and trailing `_` are trimmed) is replaced into `-` | `#[property(name = "prop-name")]` |
871/// | `type = expr` | The type of the property | inferred | `#[property(type = i32)]` |
872/// | `get [= expr]` | Specify that the property is readable and use `PropertyGet::get` [or optionally set a custom internal getter] | | `#[property(get)]`, `#[property(get = get_prop)]`, or `[property(get = \|_\| 2)]` |
873/// | `set [= expr]` | Specify that the property is writable and use `PropertySet::set` [or optionally set a custom internal setter] | | `#[property(set)]`, `#[property(set = set_prop)]`, or `[property(set = \|_, val\| {})]` |
874/// | `override_class = expr` | The type of class of which to override the property from | | `#[property(override_class = SomeClass)]` |
875/// | `override_interface = expr` | The type of interface of which to override the property from | | `#[property(override_interface = SomeInterface)]` |
876/// | `nullable` | Whether to use `Option<T>` in the generated setter method | | `#[property(nullable)]` |
877/// | `member = ident` | Field of the nested type where property is retrieved and set | | `#[property(member = author)]` |
878/// | `construct_only` | Specify that the property is construct only. This will not generate a public setter and only allow the property to be set during object construction. The use of a custom internal setter is supported. | | `#[property(get, construct_only)]` or `#[property(get, set = set_prop, construct_only)]` |
879/// | `builder(<required-params>)[.ident]*` | Used to input required params or add optional Param Spec builder fields | | `#[property(builder(SomeEnum::default()))]`, `#[builder().default_value(1).minimum(0).maximum(5)]`, etc. |
880/// | `default` | Sets the `default_value` field of the Param Spec builder | | `#[property(default = 1)]` |
881/// | `<optional-pspec-builder-fields> = expr` | Used to add optional Param Spec builder fields | | `#[property(minimum = 0)` , `#[property(minimum = 0, maximum = 1)]`, etc. |
882/// | `<optional-pspec-builder-fields>` | Used to add optional Param Spec builder fields | | `#[property(explicit_notify)]` , `#[property(construct_only)]`, etc. |
883///
884/// ## Using Rust keywords as property names
885/// You might hit a roadblock when declaring properties with this macro because you want to use a name that happens to be a Rust keyword. This may happen with names like `loop`, which is a pretty common name when creating things like animation handlers.
886/// To use those names, you can make use of the raw identifier feature of Rust. Simply prefix the identifier name with `r#` in the struct declaration. Internally, those `r#`s are stripped so you can use its expected name in [`ObjectExt::property`] or within GtkBuilder template files.
887///
888/// # Generated methods
889/// The following methods are generated on the wrapper type specified on `#[properties(wrapper_type = ...)]`:
890/// * `$property()`, when the property is readable
891/// * `set_$property()`, when the property is writable and not construct-only
892/// * `connect_$property_notify()`
893/// * `notify_$property()`
894///
895/// ## Extension trait
896/// You can choose to move the method definitions to a trait by using `#[properties(wrapper_type = super::MyType, ext_trait = MyTypePropertiesExt)]`.
897/// The trait name is optional, and defaults to `MyTypePropertiesExt`, where `MyType` is extracted from the wrapper type.
898/// Note: The trait is defined in the same module where the `#[derive(Properties)]` call happens, and is implemented on the wrapper type.
899///
900/// Notice: You can't reimplement the generated methods on the wrapper type, unless you move them to a trait.
901/// You can change the behavior of the generated getter/setter methods by using a custom internal getter/setter.
902///
903/// # Internal getters and setters
904/// By default, they are generated for you. However, you can use a custom getter/setter
905/// by assigning an expression to `get`/`set` `#[property]` attributes: `#[property(get = |_| 2, set)]` or `#[property(get, set = custom_setter_func)]`.
906///
907/// # Supported types
908/// Every type implementing the trait `Property` is supported.
909/// The type `Option<T>` is supported as a property only if `Option<T>` implements `ToValueOptional`.
910/// Optional types also require the `nullable` attribute: without it, the generated setter on the wrapper type
911/// will take `T` instead of `Option<T>`, preventing the user from ever calling the setter with a `None` value.
912///
913/// ## Adding support for custom types
914/// ### Types wrapping an existing `T: glib::value::ToValue + glib::HasParamSpec`
915/// If you have declared a newtype as
916/// ```rust
917/// struct MyInt(i32);
918/// ```
919/// you can use it as a property by deriving `glib::ValueDelegate`.
920///
921/// ### Types with inner mutability
922/// The trait `glib::Property` must be implemented.
923/// The traits `PropertyGet` and `PropertySet` should be implemented to enable the Properties macro
924/// to generate a default internal getter/setter.
925/// If possible, implementing `PropertySetNested` is preferred over `PropertySet`, because it
926/// enables this macro to access the contained type and provide access to its fields,
927/// using the `member = $structfield` syntax.
928///
929/// ### Types without `glib::HasParamSpec`
930/// If you have encountered a type `T: glib::value::ToValue`, inside the `gtk-rs` crate, which doesn't implement `HasParamSpec`,
931/// then it's a bug and you should report it.
932/// If you need to support a `ToValue` type with a `ParamSpec` not provided by `gtk-rs`, then you need to
933/// implement `glib::HasParamSpec` on that type.
934///
935/// # Example
936/// ```
937/// use std::cell::RefCell;
938/// use glib::prelude::*;
939/// use glib::subclass::prelude::*;
940/// use glib_macros::Properties;
941///
942/// #[derive(Default, Clone)]
943/// struct Author {
944/// name: String,
945/// nick: String,
946/// }
947///
948/// pub mod imp {
949/// use std::rc::Rc;
950///
951/// use super::*;
952///
953/// #[derive(Properties, Default)]
954/// #[properties(wrapper_type = super::Foo)]
955/// pub struct Foo {
956/// #[property(get, set = Self::set_fizz)]
957/// fizz: RefCell<String>,
958/// #[property(name = "author-name", get, set, type = String, member = name)]
959/// #[property(name = "author-nick", get, set, type = String, member = nick)]
960/// author: RefCell<Author>,
961/// #[property(get, set, explicit_notify, lax_validation)]
962/// custom_flags: RefCell<String>,
963/// #[property(get, set, minimum = 0, maximum = 3)]
964/// numeric_builder: RefCell<u32>,
965/// #[property(get, set, builder('c'))]
966/// builder_with_required_param: RefCell<char>,
967/// #[property(get, set, nullable)]
968/// optional: RefCell<Option<String>>,
969/// #[property(get, set)]
970/// smart_pointer: Rc<RefCell<String>>,
971/// }
972///
973/// #[glib::derived_properties]
974/// impl ObjectImpl for Foo {}
975///
976/// #[glib::object_subclass]
977/// impl ObjectSubclass for Foo {
978/// const NAME: &'static str = "MyFoo";
979/// type Type = super::Foo;
980/// }
981///
982/// impl Foo {
983/// fn set_fizz(&self, value: String) {
984/// *self.fizz.borrow_mut() = format!("custom set: {}", value);
985/// }
986/// }
987/// }
988///
989/// glib::wrapper! {
990/// pub struct Foo(ObjectSubclass<imp::Foo>);
991/// }
992///
993/// fn main() {
994/// let myfoo: Foo = glib::object::Object::new();
995///
996/// myfoo.set_fizz("test value");
997/// assert_eq!(myfoo.fizz(), "custom set: test value".to_string());
998/// }
999/// ```
1000#[allow(clippy::needless_doctest_main)]
1001#[proc_macro_derive(Properties, attributes(properties, property))]
1002pub fn derive_props(input: TokenStream) -> TokenStream {
1003 let input: PropsMacroInput = parse_macro_input!(input as properties::PropsMacroInput);
1004 properties::impl_derive_props(input)
1005}
1006
1007/// When applied to `ObjectImpl`
1008/// ```ignore
1009/// #[glib::derived_properties]
1010/// impl ObjectImpl for CustomObject
1011/// ```
1012/// this macro generates
1013/// ```ignore
1014/// impl ObjectImpl for CustomObject {
1015/// fn properties() -> &'static [glib::ParamSpec] {
1016/// Self::derived_properties()
1017/// }
1018/// fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
1019/// self.derived_set_property(id, value, pspec)
1020/// }
1021/// fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
1022/// self.derived_property(id, pspec)
1023/// }
1024/// }
1025/// ```
1026#[proc_macro_attribute]
1027#[proc_macro_error]
1028pub fn derived_properties(_attr: TokenStream, item: TokenStream) -> TokenStream {
1029 use proc_macro_error::abort_call_site;
1030 match syn::parse::<syn::ItemImpl>(tokens:item) {
1031 Ok(input: ItemImpl) => derived_properties_attribute::impl_derived_properties(&input).into(),
1032 Err(_) => abort_call_site!(derived_properties_attribute::WRONG_PLACE_MSG),
1033 }
1034}
1035
1036/// # Example
1037/// ```
1038/// use glib::prelude::*;
1039/// use glib::ValueDelegate;
1040///
1041/// #[derive(ValueDelegate, Debug, PartialEq)]
1042/// struct MyInt(i32);
1043///
1044/// let myv = MyInt(2);
1045/// let convertedv = myv.to_value();
1046/// assert_eq!(convertedv.get::<MyInt>(), Ok(myv));
1047///
1048///
1049/// #[derive(ValueDelegate, Debug, PartialEq)]
1050/// #[value_delegate(from = u32)]
1051/// enum MyEnum {
1052/// Zero,
1053/// NotZero(u32)
1054/// }
1055///
1056/// impl From<u32> for MyEnum {
1057/// fn from(v: u32) -> Self {
1058/// match v {
1059/// 0 => MyEnum::Zero,
1060/// x => MyEnum::NotZero(x)
1061/// }
1062/// }
1063/// }
1064/// impl<'a> From<&'a MyEnum> for u32 {
1065/// fn from(v: &'a MyEnum) -> Self {
1066/// match v {
1067/// MyEnum::Zero => 0,
1068/// MyEnum::NotZero(x) => *x
1069/// }
1070/// }
1071/// }
1072/// impl From<MyEnum> for u32 {
1073/// fn from(v: MyEnum) -> Self {
1074/// match v {
1075/// MyEnum::Zero => 0,
1076/// MyEnum::NotZero(x) => x
1077/// }
1078/// }
1079/// }
1080///
1081/// let myv = MyEnum::NotZero(34);
1082/// let convertedv = myv.to_value();
1083/// assert_eq!(convertedv.get::<MyEnum>(), Ok(myv));
1084///
1085///
1086/// // If you want your type to be usable inside an `Option`, you can derive `ToValueOptional`
1087/// // by adding `nullable` as follows
1088/// #[derive(ValueDelegate, Debug, PartialEq)]
1089/// #[value_delegate(nullable)]
1090/// struct MyString(String);
1091///
1092/// let myv = Some(MyString("Hello world".to_string()));
1093/// let convertedv = myv.to_value();
1094/// assert_eq!(convertedv.get::<Option<MyString>>(), Ok(myv));
1095/// let convertedv = None::<MyString>.to_value();
1096/// assert_eq!(convertedv.get::<Option<MyString>>(), Ok(None::<MyString>));
1097/// ```
1098#[proc_macro_derive(ValueDelegate, attributes(value_delegate))]
1099pub fn derive_value_delegate(input: TokenStream) -> TokenStream {
1100 let input: ValueDelegateInput = parse_macro_input!(input as value_delegate_derive::ValueDelegateInput);
1101 value_delegate_derive::impl_value_delegate(input).unwrap()
1102}
1103