glib_macros/lib.rs
1// Take a look at the license at the top of the repository in the LICENSE file.
2
3mod async_test;
4mod boxed_derive;
5mod clone;
6mod clone_old;
7mod closure;
8mod closure_old;
9mod derived_properties_attribute;
10mod downgrade_derive;
11mod enum_derive;
12mod error_domain_derive;
13mod flags_attribute;
14mod object_impl_attributes;
15mod properties;
16mod shared_boxed_derive;
17mod value_delegate_derive;
18mod variant_derive;
19
20mod utils;
21
22use flags_attribute::AttrInput;
23use proc_macro::{TokenStream, TokenTree};
24use proc_macro2::Span;
25use syn::{parse_macro_input, DeriveInput};
26use utils::{parse_nested_meta_items_from_stream, NestedMetaItem};
27
28/// Macro for passing variables as strong or weak references into a closure.
29///
30/// This macro can be useful in combination with closures, e.g. signal handlers, to reduce the
31/// boilerplate required for passing strong or weak references into the closure. It will
32/// automatically create the new reference and pass it with the same name into the closure.
33///
34/// If upgrading the weak reference to a strong reference inside the closure is failing, the
35/// closure is immediately returning an optional default return value. If none is provided, `()` is
36/// returned.
37///
38/// **⚠️ IMPORTANT ⚠️**
39///
40/// `glib` needs to be in scope, so unless it's one of the direct crate dependencies, you need to
41/// import it because `clone!` is using it. For example:
42///
43/// ```rust,ignore
44/// use gtk::glib;
45/// ```
46///
47/// ### Debugging
48///
49/// In case something goes wrong inside the `clone!` macro, we use the [`g_debug`] macro. Meaning
50/// that if you want to see these debug messages, you'll have to set the `G_MESSAGES_DEBUG`
51/// environment variable when running your code (either in the code directly or when running the
52/// binary) to either "all" or [`CLONE_MACRO_LOG_DOMAIN`]:
53///
54/// [`g_debug`]: ../glib/macro.g_debug.html
55/// [`CLONE_MACRO_LOG_DOMAIN`]: ../glib/constant.CLONE_MACRO_LOG_DOMAIN.html
56///
57/// ```rust,ignore
58/// use glib::CLONE_MACRO_LOG_DOMAIN;
59///
60/// std::env::set_var("G_MESSAGES_DEBUG", CLONE_MACRO_LOG_DOMAIN);
61/// std::env::set_var("G_MESSAGES_DEBUG", "all");
62/// ```
63///
64/// Or:
65///
66/// ```bash
67/// $ G_MESSAGES_DEBUG=all ./binary
68/// ```
69///
70/// ### Passing a strong reference
71///
72/// ```
73/// use glib;
74/// use glib_macros::clone;
75/// use std::rc::Rc;
76///
77/// let v = Rc::new(1);
78/// let closure = clone!(
79/// #[strong] v,
80/// move |x| {
81/// println!("v: {}, x: {}", v, x);
82/// },
83/// );
84///
85/// closure(2);
86/// ```
87///
88/// ### Passing a weak reference
89///
90/// ```
91/// use glib;
92/// use glib_macros::clone;
93/// use std::rc::Rc;
94///
95/// let u = Rc::new(2);
96/// let closure = clone!(
97/// #[weak]
98/// u,
99/// move |x| {
100/// println!("u: {}, x: {}", u, x);
101/// },
102/// );
103///
104/// closure(3);
105/// ```
106///
107/// #### Allowing a nullable weak reference
108///
109/// In some cases, even if the weak references can't be retrieved, you might want to still have
110/// your closure called. In this case, you need to use `#[weak_allow_none]` instead of `#[weak]`:
111///
112/// ```
113/// use glib;
114/// use glib_macros::clone;
115/// use std::rc::Rc;
116///
117/// let closure = {
118/// // This `Rc` won't be available in the closure because it's dropped at the end of the
119/// // current block
120/// let u = Rc::new(2);
121/// clone!(
122/// #[weak_allow_none]
123/// u,
124/// move |x| {
125/// // We need to use a Debug print for `u` because it'll be an `Option`.
126/// println!("u: {:?}, x: {}", u, x);
127/// true
128/// },
129/// )
130/// };
131///
132/// assert_eq!(closure(3), true);
133/// ```
134///
135/// ### Creating owned values from references (`ToOwned`)
136///
137/// ```
138/// use glib;
139/// use glib_macros::clone;
140///
141/// let v = "123";
142/// let closure = clone!(
143/// #[to_owned] v,
144/// move |x| {
145/// // v is passed as `String` here
146/// println!("v: {}, x: {}", v, x);
147/// },
148/// );
149///
150/// closure(2);
151/// ```
152///
153/// ### Renaming variables
154///
155/// ```
156/// use glib;
157/// use glib_macros::clone;
158/// use std::rc::Rc;
159///
160/// let v = Rc::new(1);
161/// let u = Rc::new(2);
162/// let closure = clone!(
163/// #[strong(rename_to = y)]
164/// v,
165/// #[weak] u,
166/// move |x| {
167/// println!("v as y: {}, u: {}, x: {}", y, u, x);
168/// },
169/// );
170///
171/// closure(3);
172/// ```
173///
174/// ### Providing a return value if upgrading a weak reference fails
175///
176/// By default, `()` is returned if upgrading a weak reference fails. This behaviour can be
177/// adjusted in two different ways:
178///
179/// Either by providing the value yourself using one of
180///
181/// * `#[upgrade_or]`: Requires an expression that returns a `Copy` value of the expected return type,
182/// * `#[upgrade_or_else]`: Requires a closure that returns a value of the expected return type,
183/// * `#[upgrade_or_default]`: Requires that the return type implements `Default` and returns that.
184///
185/// ```
186/// use glib;
187/// use glib_macros::clone;
188/// use std::rc::Rc;
189///
190/// let v = Rc::new(1);
191/// let closure = clone!(
192/// #[weak] v,
193/// #[upgrade_or]
194/// false,
195/// move |x| {
196/// println!("v: {}, x: {}", v, x);
197/// true
198/// },
199/// );
200///
201/// // Drop value so that the weak reference can't be upgraded.
202/// drop(v);
203///
204/// assert_eq!(closure(2), false);
205/// ```
206///
207/// Or by using `#[upgrade_or_panic]`: If the value fails to get upgraded, it'll panic.
208///
209/// ```should_panic
210/// # use glib;
211/// # use glib_macros::clone;
212/// # use std::rc::Rc;
213/// # let v = Rc::new(1);
214/// let closure = clone!(
215/// #[weak] v,
216/// #[upgrade_or_panic]
217/// move |x| {
218/// println!("v: {}, x: {}", v, x);
219/// true
220/// },
221/// );
222/// # drop(v);
223/// # assert_eq!(closure(2), false);
224/// ```
225///
226/// ### Errors
227///
228/// Here is a list of errors you might encounter:
229///
230/// **Missing `#[weak]` or `#[strong]`**:
231///
232/// ```compile_fail
233/// # use glib;
234/// # use glib_macros::clone;
235/// # use std::rc::Rc;
236/// let v = Rc::new(1);
237///
238/// let closure = clone!(
239/// v,
240/// move |x| println!("v: {}, x: {}", v, x),
241/// );
242/// # drop(v);
243/// # closure(2);
244/// ```
245///
246/// **Passing `self` as an argument**:
247///
248/// ```compile_fail
249/// # use glib;
250/// # use glib_macros::clone;
251/// # use std::rc::Rc;
252/// #[derive(Debug)]
253/// struct Foo;
254///
255/// impl Foo {
256/// fn foo(&self) {
257/// let closure = clone!(
258/// #[strong] self,
259/// move |x| {
260/// println!("self: {:?}", self);
261/// },
262/// );
263/// # closure(2);
264/// }
265/// }
266/// ```
267///
268/// If you want to use `self` directly, you'll need to rename it:
269///
270/// ```
271/// # use glib;
272/// # use glib_macros::clone;
273/// # use std::rc::Rc;
274/// #[derive(Debug)]
275/// struct Foo;
276///
277/// impl Foo {
278/// fn foo(&self) {
279/// let closure = clone!(
280/// #[strong(rename_to = this)]
281/// self,
282/// move |x| {
283/// println!("self: {:?}", this);
284/// },
285/// );
286/// # closure(2);
287/// }
288/// }
289/// ```
290///
291/// **Passing fields directly**
292///
293/// ```compile_fail
294/// # use glib;
295/// # use glib_macros::clone;
296/// # use std::rc::Rc;
297/// #[derive(Debug)]
298/// struct Foo {
299/// v: Rc<usize>,
300/// }
301///
302/// impl Foo {
303/// fn foo(&self) {
304/// let closure = clone!(
305/// #[strong] self.v,
306/// move |x| {
307/// println!("self.v: {:?}", v);
308/// },
309/// );
310/// # closure(2);
311/// }
312/// }
313/// ```
314///
315/// You can do it by renaming it:
316///
317/// ```
318/// # use glib;
319/// # use glib_macros::clone;
320/// # use std::rc::Rc;
321/// # struct Foo {
322/// # v: Rc<usize>,
323/// # }
324/// impl Foo {
325/// fn foo(&self) {
326/// let closure = clone!(
327/// #[strong(rename_to = v)]
328/// self.v,
329/// move |x| {
330/// println!("self.v: {}", v);
331/// },
332/// );
333/// # closure(2);
334/// }
335/// }
336/// ```
337#[proc_macro]
338pub fn clone(item: TokenStream) -> TokenStream {
339 // Check if this is an old-style clone macro invocation.
340 // These always start with an '@' punctuation.
341 let Some(first) = item.clone().into_iter().next() else {
342 return syn::Error::new(Span::call_site(), "expected a closure or async block")
343 .to_compile_error()
344 .into();
345 };
346
347 match first {
348 TokenTree::Punct(ref p) if p.to_string() == "@" => clone_old::clone_inner(item),
349 _ => clone::clone_inner(item),
350 }
351}
352
353/// Macro for creating a [`Closure`] object. This is a wrapper around [`Closure::new`] that
354/// automatically type checks its arguments at run-time.
355///
356/// A `Closure` takes [`Value`] objects as inputs and output. This macro will automatically convert
357/// the inputs to Rust types when invoking its callback, and then will convert the output back to a
358/// `Value`. All inputs must implement the [`FromValue`] trait, and outputs must either implement
359/// the [`ToValue`] trait or be the unit type `()`. Type-checking of inputs is done at run-time; if
360/// incorrect types are passed via [`Closure::invoke`] then the closure will panic. Note that when
361/// passing input types derived from [`Object`] or [`Interface`], you must take care to upcast to
362/// the exact object or interface type that is being received.
363///
364/// Similarly to [`clone!`](crate::clone!), this macro can be useful in combination with signal
365/// handlers to reduce boilerplate when passing references. Unique to `Closure` objects is the
366/// ability to watch an object using the `#[watch]` attribute. Only an [`Object`] value can be
367/// passed to `#[watch]`, and only one object can be watched per closure. When an object is watched,
368/// a weak reference to the object is held in the closure. When the object is destroyed, the
369/// closure will become invalidated: all signal handlers connected to the closure will become
370/// disconnected, and any calls to [`Closure::invoke`] on the closure will be silently ignored.
371/// Internally, this is accomplished using [`Object::watch_closure`] on the watched object.
372///
373/// The `#[weak]`, `#[weak_allow_none]`, `#[strong]`, `#[to_owned]` captures are also supported and
374/// behave the same as in [`clone!`](crate::clone!), as is aliasing captures via `rename_to`.
375/// Similarly, upgrade failure of weak references can be adjusted via `#[upgrade_or]`,
376/// `#[upgrade_or_else]`, `#[upgrade_or_default]` and `#[upgrade_or_panic]`.
377///
378/// Notably, these captures are able to reference `Rc` and `Arc` values in addition to `Object`
379/// values.
380///
381/// [`Closure`]: ../glib/closure/struct.Closure.html
382/// [`Closure::new`]: ../glib/closure/struct.Closure.html#method.new
383/// [`Closure::new_local`]: ../glib/closure/struct.Closure.html#method.new_local
384/// [`Closure::invoke`]: ../glib/closure/struct.Closure.html#method.invoke
385/// [`Value`]: ../glib/value/struct.Value.html
386/// [`FromValue`]: ../glib/value/trait.FromValue.html
387/// [`ToValue`]: ../glib/value/trait.ToValue.html
388/// [`Interface`]: ../glib/object/struct.Interface.html
389/// [`Object`]: ../glib/object/struct.Object.html
390/// [`Object::watch_closure`]: ../glib/object/trait.ObjectExt.html#tymethod.watch_closure
391/// **⚠️ IMPORTANT ⚠️**
392///
393/// `glib` needs to be in scope, so unless it's one of the direct crate dependencies, you need to
394/// import it because `closure!` is using it. For example:
395///
396/// ```rust,ignore
397/// use gtk::glib;
398/// ```
399///
400/// ### Using as a closure object
401///
402/// ```
403/// use glib_macros::closure;
404///
405/// let concat_str = closure!(|s: &str| s.to_owned() + " World");
406/// let result = concat_str.invoke::<String>(&[&"Hello"]);
407/// assert_eq!(result, "Hello World");
408/// ```
409///
410/// ### Connecting to a signal
411///
412/// For wrapping closures that can't be sent across threads, the
413/// [`closure_local!`](crate::closure_local!) macro can be used. It has the same syntax as
414/// `closure!`, but instead uses [`Closure::new_local`] internally.
415///
416/// ```
417/// use glib;
418/// use glib::prelude::*;
419/// use glib_macros::closure_local;
420///
421/// let obj = glib::Object::new::<glib::Object>();
422/// obj.connect_closure(
423/// "notify", false,
424/// closure_local!(|_obj: glib::Object, pspec: glib::ParamSpec| {
425/// println!("property notify: {}", pspec.name());
426/// }));
427/// ```
428///
429/// ### Object Watching
430///
431/// ```
432/// use glib;
433/// use glib::prelude::*;
434/// use glib_macros::closure_local;
435///
436/// let closure = {
437/// let obj = glib::Object::new::<glib::Object>();
438/// let closure = closure_local!(
439/// #[watch] obj,
440/// move || {
441/// obj.type_().name()
442/// },
443/// );
444/// assert_eq!(closure.invoke::<String>(&[]), "GObject");
445/// closure
446/// };
447/// // `obj` is dropped, closure invalidated so it always does nothing and returns None
448/// closure.invoke::<()>(&[]);
449/// ```
450///
451/// `#[watch]` has special behavior when connected to a signal:
452///
453/// ```
454/// use glib;
455/// use glib::prelude::*;
456/// use glib_macros::closure_local;
457///
458/// let obj = glib::Object::new::<glib::Object>();
459/// {
460/// let other = glib::Object::new::<glib::Object>();
461/// obj.connect_closure(
462/// "notify", false,
463/// closure_local!(
464/// #[watch(rename_to = b)]
465/// other,
466/// move |a: glib::Object, pspec: glib::ParamSpec| {
467/// let value = a.property_value(pspec.name());
468/// b.set_property(pspec.name(), &value);
469/// },
470/// ),
471/// );
472/// // The signal handler will disconnect automatically at the end of this
473/// // block when `other` is dropped.
474/// }
475/// ```
476///
477/// ### Weak and Strong References
478///
479/// ```
480/// use glib;
481/// use glib::prelude::*;
482/// use glib_macros::closure;
483/// use std::sync::Arc;
484///
485/// let closure = {
486/// let a = Arc::new(String::from("Hello"));
487/// let b = Arc::new(String::from("World"));
488/// let c = "!";
489/// let closure = closure!(
490/// #[strong] a,
491/// #[weak_allow_none]
492/// b,
493/// #[to_owned]
494/// c,
495/// move || {
496/// // `a` is Arc<String>, `b` is Option<Arc<String>>, `c` is a `String`
497/// format!("{} {}{}", a, b.as_ref().map(|b| b.as_str()).unwrap_or_else(|| "Moon"), c)
498/// },
499/// );
500/// assert_eq!(closure.invoke::<String>(&[]), "Hello World!");
501/// closure
502/// };
503/// // `a`, `c` still kept alive, `b` is dropped
504/// assert_eq!(closure.invoke::<String>(&[]), "Hello Moon!");
505/// ```
506#[proc_macro]
507pub fn closure(item: TokenStream) -> TokenStream {
508 // Check if this is an old-style closure macro invocation.
509 // These always start with an '@' punctuation.
510 let Some(first) = item.clone().into_iter().next() else {
511 return syn::Error::new(Span::call_site(), "expected a closure")
512 .to_compile_error()
513 .into();
514 };
515
516 match first {
517 TokenTree::Punct(ref p) if p.to_string() == "@" => closure_old::closure_inner(item, "new"),
518 _ => closure::closure_inner(item, "new"),
519 }
520}
521
522/// The same as [`closure!`](crate::closure!) but uses [`Closure::new_local`] as a constructor.
523/// This is useful for closures which can't be sent across threads. See the documentation of
524/// [`closure!`](crate::closure!) for details.
525///
526/// [`Closure::new_local`]: ../glib/closure/struct.Closure.html#method.new_local
527#[proc_macro]
528pub fn closure_local(item: TokenStream) -> TokenStream {
529 // Check if this is an old-style closure macro invocation.
530 // These always start with an '@' punctuation.
531 let Some(first) = item.clone().into_iter().next() else {
532 return syn::Error::new(Span::call_site(), "expected a closure")
533 .to_compile_error()
534 .into();
535 };
536
537 match first {
538 TokenTree::Punct(ref p) if p.to_string() == "@" => {
539 closure_old::closure_inner(item, "new_local")
540 }
541 _ => closure::closure_inner(item, "new_local"),
542 }
543}
544
545/// Derive macro to register a Rust enum in the GLib type system and derive the
546/// [`glib::Value`] traits.
547///
548/// # Example
549///
550/// ```
551/// use glib::prelude::*;
552/// use glib::subclass::prelude::*;
553///
554/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
555/// #[enum_type(name = "MyEnum")]
556/// enum MyEnum {
557/// Val,
558/// #[enum_value(name = "My Val")]
559/// ValWithCustomName,
560/// #[enum_value(name = "My Other Val", nick = "other")]
561/// ValWithCustomNameAndNick,
562/// }
563/// ```
564///
565/// When using the [`Properties`] macro with enums that derive [`Enum`], the default value must be
566/// explicitly set via the `builder` parameter of the `#[property]` attribute. See
567/// [here](Properties#supported-types) for details.
568///
569/// An enum can be registered as a dynamic type by setting the derive macro
570/// helper attribute `enum_dynamic`:
571///
572/// ```ignore
573/// use glib::prelude::*;
574/// use glib::subclass::prelude::*;
575///
576/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
577/// #[enum_type(name = "MyEnum")]
578/// #[enum_dynamic]
579/// enum MyEnum {
580/// ...
581/// }
582/// ```
583///
584/// As a dynamic type, an enum must be explicitly registered when the system
585/// loads the implementation (see [`TypePlugin`] and [`TypeModule`]).
586/// Therefore, whereas an enum can be registered only once as a static type,
587/// it can be registered several times as a dynamic type.
588///
589/// An enum registered as a dynamic type is never unregistered. The system
590/// calls [`TypePluginExt::unuse`] to unload the implementation. If the
591/// [`TypePlugin`] subclass is a [`TypeModule`], the enum registered as a
592/// dynamic type is marked as unloaded and must be registered again when the
593/// module is reloaded.
594///
595/// The derive macro helper attribute `enum_dynamic` provides two behaviors
596/// when registering an enum as a dynamic type:
597///
598/// - lazy registration: by default an enum is registered as a dynamic type
599/// when the system loads the implementation (e.g. when the module is loaded).
600/// Optionally setting `lazy_registration` to `true` postpones registration on
601/// the first use (when `static_type()` is called for the first time):
602///
603/// ```ignore
604/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
605/// #[enum_type(name = "MyEnum")]
606/// #[enum_dynamic(lazy_registration = true)]
607/// enum MyEnum {
608/// ...
609/// }
610/// ```
611///
612/// - registration within [`TypeModule`] subclass or within [`TypePlugin`]
613/// subclass: an enum is usually registered as a dynamic type within a
614/// [`TypeModule`] subclass:
615///
616/// ```ignore
617/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
618/// #[enum_type(name = "MyModuleEnum")]
619/// #[enum_dynamic]
620/// enum MyModuleEnum {
621/// ...
622/// }
623/// ...
624/// #[derive(Default)]
625/// pub struct MyModule;
626/// ...
627/// impl TypeModuleImpl for MyModule {
628/// fn load(&self) -> bool {
629/// // registers enums as dynamic types.
630/// let my_module = self.obj();
631/// let type_module: &glib::TypeModule = my_module.upcast_ref();
632/// MyModuleEnum::on_implementation_load(type_module)
633/// }
634/// ...
635/// }
636/// ```
637///
638/// Optionally setting `plugin_type` allows to register an enum as a dynamic
639/// type within a [`TypePlugin`] subclass that is not a [`TypeModule`]:
640///
641/// ```ignore
642/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
643/// #[enum_type(name = "MyPluginEnum")]
644/// #[enum_dynamic(plugin_type = MyPlugin)]
645/// enum MyPluginEnum {
646/// ...
647/// }
648/// ...
649/// #[derive(Default)]
650/// pub struct MyPlugin;
651/// ...
652/// impl TypePluginImpl for MyPlugin {
653/// fn use_plugin(&self) {
654/// // register enums as dynamic types.
655/// let my_plugin = self.obj();
656/// MyPluginEnum::on_implementation_load(my_plugin.as_ref());
657/// }
658/// ...
659/// }
660/// ```
661///
662/// [`glib::Value`]: ../glib/value/struct.Value.html
663/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
664/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
665/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.
666#[proc_macro_derive(Enum, attributes(enum_type, enum_dynamic, enum_value))]
667pub fn enum_derive(input: TokenStream) -> TokenStream {
668 let input = parse_macro_input!(input as DeriveInput);
669 enum_derive::impl_enum(&input)
670 .unwrap_or_else(syn::Error::into_compile_error)
671 .into()
672}
673
674/// Attribute macro for defining flags using the `bitflags` crate.
675/// This macro will also define a `GFlags::type_` function and
676/// the [`glib::Value`] traits.
677///
678/// The expected `GType` name has to be passed as macro attribute.
679/// The name and nick of each flag can also be optionally defined.
680/// Default name is the flag identifier in CamelCase and default nick
681/// is the identifier in kebab-case.
682/// Combined flags should not be registered with the `GType` system
683/// and so need to be tagged with the `#[flags_value(skip)]` attribute.
684///
685/// # Example
686///
687/// ```
688/// use glib::prelude::*;
689/// use glib::subclass::prelude::*;
690///
691/// #[glib::flags(name = "MyFlags")]
692/// enum MyFlags {
693/// #[flags_value(name = "Flag A", nick = "nick-a")]
694/// A = 0b00000001,
695/// #[flags_value(name = "Flag B")]
696/// B = 0b00000010,
697/// #[flags_value(skip)]
698/// AB = Self::A.bits() | Self::B.bits(),
699/// C = 0b00000100,
700/// }
701/// ```
702///
703/// The flags can be registered as a dynamic type by setting the macro helper
704/// attribute `flags_dynamic`:
705/// ```ignore
706/// use glib::prelude::*;
707/// use glib::subclass::prelude::*;
708///
709/// #[glib::flags(name = "MyFlags")]
710/// #[flags_dynamic]
711/// enum MyFlags {
712/// ...
713/// }
714/// ```
715///
716/// As a dynamic type, the flags must be explicitly registered when the system
717/// loads the implementation (see [`TypePlugin`] and [`TypeModule`]).
718/// Therefore, whereas the flags can be registered only once as a static type,
719/// they can be registered several times as a dynamic type.
720///
721/// The flags registered as a dynamic type are never unregistered. The system
722/// calls [`TypePluginExt::unuse`] to unload the implementation. If the
723/// [`TypePlugin`] subclass is a [`TypeModule`], the flags registered as a
724/// dynamic type are marked as unloaded and must be registered again when the
725/// module is reloaded.
726///
727/// The macro helper attribute `flags_dynamic` provides two behaviors when
728/// registering the flags as a dynamic type:
729///
730/// - lazy registration: by default the flags are registered as a dynamic type
731/// when the system loads the implementation (e.g. when the module is loaded).
732/// Optionally setting `lazy_registration` to `true` postpones registration on
733/// the first use (when `static_type()` is called for the first time):
734///
735/// ```ignore
736/// #[glib::flags(name = "MyFlags")]
737/// #[flags_dynamic(lazy_registration = true)]
738/// enum MyFlags {
739/// ...
740/// }
741/// ```
742///
743/// - registration within [`TypeModule`] subclass or within [`TypePlugin`]
744/// subclass: the flags are usually registered as a dynamic type within a
745/// [`TypeModule`] subclass:
746///
747/// ```ignore
748/// #[glib::flags(name = "MyModuleFlags")]
749/// #[flags_dynamic]
750/// enum MyModuleFlags {
751/// ...
752/// }
753/// ...
754/// #[derive(Default)]
755/// pub struct MyModule;
756/// ...
757/// impl TypeModuleImpl for MyModule {
758/// fn load(&self) -> bool {
759/// // registers flags as dynamic types.
760/// let my_module = self.obj();
761/// let type_module: &glib::TypeModule = my_module.upcast_ref();
762/// MyModuleFlags::on_implementation_load(type_module)
763/// }
764/// ...
765/// }
766/// ```
767///
768/// Optionally setting `plugin_type` allows to register the flags as a dynamic
769/// type within a [`TypePlugin`] subclass that is not a [`TypeModule`]:
770/// ```ignore
771/// #[glib::flags(name = "MyModuleFlags")]
772/// #[flags_dynamic(plugin_type = MyPlugin)]
773/// enum MyModuleFlags {
774/// ...
775/// }
776/// ...
777/// #[derive(Default)]
778/// pub struct MyPlugin;
779/// ...
780/// impl TypePluginImpl for MyPlugin {
781/// fn use_plugin(&self) {
782/// // register flags as dynamic types.
783/// let my_plugin = self.obj();
784/// MyPluginFlags::on_implementation_load(my_plugin.as_ref());
785/// }
786/// ...
787/// }
788/// ```
789///
790/// [`glib::Value`]: ../glib/value/struct.Value.html
791/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
792/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
793/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.
794#[proc_macro_attribute]
795pub fn flags(attr: TokenStream, item: TokenStream) -> TokenStream {
796 let mut name = NestedMetaItem::<syn::LitStr>::new("name")
797 .required()
798 .value_required();
799 let mut allow_name_conflict_attr =
800 NestedMetaItem::<syn::LitBool>::new("allow_name_conflict").value_optional();
801
802 if let Err(e) = parse_nested_meta_items_from_stream(
803 attr.into(),
804 &mut [&mut name, &mut allow_name_conflict_attr],
805 ) {
806 return e.to_compile_error().into();
807 }
808
809 let allow_name_conflict = allow_name_conflict_attr.found
810 || allow_name_conflict_attr
811 .value
812 .map(|b| b.value())
813 .unwrap_or(false);
814
815 let attr_meta = AttrInput {
816 enum_name: name.value.unwrap(),
817 allow_name_conflict,
818 };
819
820 syn::parse::<syn::ItemEnum>(item)
821 .map_err(|_| syn::Error::new(Span::call_site(), flags_attribute::WRONG_PLACE_MSG))
822 .map(|mut input| flags_attribute::impl_flags(attr_meta, &mut input))
823 .unwrap_or_else(syn::Error::into_compile_error)
824 .into()
825}
826
827/// Derive macro for defining a GLib error domain and its associated
828/// [`ErrorDomain`] trait.
829///
830/// # Example
831///
832/// ```
833/// use glib::prelude::*;
834/// use glib::subclass::prelude::*;
835///
836/// #[derive(Debug, Copy, Clone, glib::ErrorDomain)]
837/// #[error_domain(name = "ex-foo")]
838/// enum Foo {
839/// Blah,
840/// Baaz,
841/// }
842/// ```
843///
844/// [`ErrorDomain`]: ../glib/error/trait.ErrorDomain.html
845#[proc_macro_derive(ErrorDomain, attributes(error_domain))]
846pub fn error_domain_derive(input: TokenStream) -> TokenStream {
847 let input = parse_macro_input!(input as DeriveInput);
848 error_domain_derive::impl_error_domain(&input)
849 .unwrap_or_else(syn::Error::into_compile_error)
850 .into()
851}
852
853/// Derive macro for defining a [`BoxedType`]`::type_` function and
854/// the [`glib::Value`] traits. Optionally, the type can be marked as
855/// `nullable` to get an implementation of `glib::value::ToValueOptional`.
856///
857/// # Example
858///
859/// ```
860/// use glib::prelude::*;
861/// use glib::subclass::prelude::*;
862///
863/// #[derive(Clone, Debug, PartialEq, Eq, glib::Boxed)]
864/// #[boxed_type(name = "MyBoxed")]
865/// struct MyBoxed(String);
866///
867/// #[derive(Clone, Debug, PartialEq, Eq, glib::Boxed)]
868/// #[boxed_type(name = "MyNullableBoxed", nullable)]
869/// struct MyNullableBoxed(String);
870/// ```
871///
872/// [`BoxedType`]: ../glib/subclass/boxed/trait.BoxedType.html
873/// [`glib::Value`]: ../glib/value/struct.Value.html
874#[proc_macro_derive(Boxed, attributes(boxed_type))]
875pub fn boxed_derive(input: TokenStream) -> TokenStream {
876 let input = parse_macro_input!(input as DeriveInput);
877 boxed_derive::impl_boxed(&input)
878 .unwrap_or_else(syn::Error::into_compile_error)
879 .into()
880}
881
882/// Derive macro for defining a [`SharedType`]`::get_type` function and
883/// the [`glib::Value`] traits. Optionally, the type can be marked as
884/// `nullable` to get an implementation of `glib::value::ToValueOptional`.
885///
886/// # Example
887///
888/// ```
889/// use glib::prelude::*;
890/// use glib::subclass::prelude::*;
891///
892/// #[derive(Clone, Debug, PartialEq, Eq)]
893/// struct MySharedInner {
894/// foo: String,
895/// }
896///
897/// #[derive(Clone, Debug, PartialEq, Eq, glib::SharedBoxed)]
898/// #[shared_boxed_type(name = "MySharedBoxed")]
899/// struct MySharedBoxed(std::sync::Arc<MySharedInner>);
900///
901/// #[derive(Clone, Debug, PartialEq, Eq, glib::SharedBoxed)]
902/// #[shared_boxed_type(name = "MyNullableSharedBoxed", nullable)]
903/// struct MyNullableSharedBoxed(std::sync::Arc<MySharedInner>);
904/// ```
905///
906/// [`SharedType`]: ../glib/subclass/shared/trait.SharedType.html
907/// [`glib::Value`]: ../glib/value/struct.Value.html
908#[proc_macro_derive(SharedBoxed, attributes(shared_boxed_type))]
909pub fn shared_boxed_derive(input: TokenStream) -> TokenStream {
910 let input = parse_macro_input!(input as DeriveInput);
911 shared_boxed_derive::impl_shared_boxed(&input)
912 .unwrap_or_else(syn::Error::into_compile_error)
913 .into()
914}
915
916/// Macro for boilerplate of [`ObjectSubclass`] implementations.
917///
918/// This adds implementations for the `type_data()` and `type_()` methods,
919/// which should probably never be defined differently.
920///
921/// It provides default values for the `Instance`, `Class`, and `Interfaces`
922/// type parameters. If these are present, the macro will use the provided value
923/// instead of the default.
924///
925/// Usually the defaults for `Instance` and `Class` will work. `Interfaces` is
926/// necessary for types that implement interfaces.
927///
928/// ```ignore
929/// type Instance = glib::subclass::basic::InstanceStruct<Self>;
930/// type Class = glib::subclass::basic::ClassStruct<Self>;
931/// type Interfaces = ();
932/// ```
933///
934/// If no `new()` or `with_class()` method is provided, the macro adds a `new()`
935/// implementation calling `Default::default()`. So the type needs to implement
936/// `Default`, or this should be overridden.
937///
938/// ```ignore
939/// fn new() -> Self {
940/// Default::default()
941/// }
942/// ```
943///
944/// An object subclass can be registered as a dynamic type by setting the macro
945/// helper attribute `object_class_dynamic`:
946///
947/// ```ignore
948/// #[derive(Default)]
949/// pub struct MyType;
950///
951/// #[glib::object_subclass]
952/// #[object_subclass_dynamic]
953/// impl ObjectSubclass for MyType { ... }
954/// ```
955///
956/// As a dynamic type, an object subclass must be explicitly registered when
957/// the system loads the implementation (see [`TypePlugin`] and [`TypeModule`]).
958/// Therefore, whereas an object subclass can be registered only once as a
959/// static type, it can be registered several times as a dynamic type.
960///
961/// An object subclass registered as a dynamic type is never unregistered. The
962/// system calls [`TypePluginExt::unuse`] to unload the implementation. If the
963/// [`TypePlugin`] subclass is a [`TypeModule`], the object subclass registered
964/// as a dynamic type is marked as unloaded and must be registered again when
965/// the module is reloaded.
966///
967/// The macro helper attribute `object_class_dynamic` provides two behaviors
968/// when registering an object subclass as a dynamic type:
969///
970/// - lazy registration: by default an object subclass is registered as a
971/// dynamic type when the system loads the implementation (e.g. when the module
972/// is loaded). Optionally setting `lazy_registration` to `true` postpones
973/// registration on the first use (when `static_type()` is called for the first
974/// time):
975///
976/// ```ignore
977/// #[derive(Default)]
978/// pub struct MyType;
979///
980/// #[glib::object_subclass]
981/// #[object_subclass_dynamic(lazy_registration = true)]
982/// impl ObjectSubclass for MyType { ... }
983/// ```
984///
985/// - registration within [`TypeModule`] subclass or within [`TypePlugin`]
986/// subclass: an object subclass is usually registered as a dynamic type within
987/// a [`TypeModule`] subclass:
988///
989/// ```ignore
990/// #[derive(Default)]
991/// pub struct MyModuleType;
992///
993/// #[glib::object_subclass]
994/// #[object_subclass_dynamic]
995/// impl ObjectSubclass for MyModuleType { ... }
996/// ...
997/// #[derive(Default)]
998/// pub struct MyModule;
999/// ...
1000/// impl TypeModuleImpl for MyModule {
1001/// fn load(&self) -> bool {
1002/// // registers object subclasses as dynamic types.
1003/// let my_module = self.obj();
1004/// let type_module: &glib::TypeModule = my_module.upcast_ref();
1005/// MyModuleType::on_implementation_load(type_module)
1006/// }
1007/// ...
1008/// }
1009/// ```
1010///
1011/// Optionally setting `plugin_type` allows to register an object subclass as a
1012/// dynamic type within a [`TypePlugin`] subclass that is not a [`TypeModule`]:
1013///
1014/// ```ignore
1015/// #[derive(Default)]
1016/// pub struct MyPluginType;
1017///
1018/// #[glib::object_subclass]
1019/// #[object_subclass_dynamic(plugin_type = MyPlugin)]
1020/// impl ObjectSubclass for MyPluginType { ... }
1021/// ...
1022/// #[derive(Default)]
1023/// pub struct MyPlugin;
1024/// ...
1025/// impl TypePluginImpl for MyPlugin {
1026/// fn use_plugin(&self) {
1027/// // register object subclasses as dynamic types.
1028/// let my_plugin = self.obj();
1029/// MyPluginType::on_implementation_load(my_plugin.as_ref());
1030/// }
1031/// ...
1032/// }
1033/// ```
1034///
1035/// [`ObjectSubclass`]: ../glib/subclass/types/trait.ObjectSubclass.html
1036/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
1037/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
1038/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.html#method.unuse
1039#[proc_macro_attribute]
1040pub fn object_subclass(_attr: TokenStream, item: TokenStream) -> TokenStream {
1041 let input = parse_macro_input!(item with object_impl_attributes::Input::parse_subclass);
1042 object_impl_attributes::subclass::impl_object_subclass(input).into()
1043}
1044
1045/// Macro for boilerplate of [`ObjectInterface`] implementations.
1046///
1047/// This adds implementations for the `get_type()` method, which should probably never be defined
1048/// differently.
1049///
1050/// It provides default values for the `Prerequisites` type parameter. If this is present, the macro
1051/// will use the provided value instead of the default.
1052///
1053/// `Prerequisites` are interfaces for types that require a specific base class or interfaces.
1054///
1055/// ```ignore
1056/// type Prerequisites = ();
1057/// ```
1058///
1059/// An object interface can be registered as a dynamic type by setting the
1060/// macro helper attribute `object_interface_dynamic`:
1061/// ```ignore
1062/// pub struct MyInterface {
1063/// parent: glib::gobject_ffi::GTypeInterface,
1064/// }
1065/// #[glib::object_interface]
1066/// #[object_interface_dynamic]
1067/// unsafe impl ObjectInterface for MyInterface { ... }
1068/// ```
1069///
1070/// As a dynamic type, an object interface must be explicitly registered when
1071/// the system loads the implementation (see [`TypePlugin`] and [`TypeModule`]).
1072/// Therefore, whereas an object interface can be registered only once as a
1073/// static type, it can be registered several times as a dynamic type.
1074///
1075/// An object interface registered as a dynamic type is never unregistered. The
1076/// system calls [`TypePluginExt::unuse`] to unload the implementation. If the
1077/// [`TypePlugin`] subclass is a [`TypeModule`], the object interface
1078/// registered as a dynamic type is marked as unloaded and must be registered
1079/// again when the module is reloaded.
1080///
1081/// The macro helper attribute `object_interface_dynamic` provides two
1082/// behaviors when registering an object interface as a dynamic type:
1083///
1084/// - lazy registration: by default an object interface is registered as a
1085/// dynamic type when the system loads the implementation (e.g. when the module
1086/// is loaded). Optionally setting `lazy_registration` to `true` postpones
1087/// registration on the first use (when `type_()` is called for the first time):
1088///
1089/// ```ignore
1090/// pub struct MyInterface {
1091/// parent: glib::gobject_ffi::GTypeInterface,
1092/// }
1093/// #[glib::object_interface]
1094/// #[object_interface_dynamic(lazy_registration = true)]
1095/// unsafe impl ObjectInterface for MyInterface { ... }
1096/// ```
1097///
1098/// - registration within [`TypeModule`] subclass or within [`TypePlugin`]
1099/// subclass: an object interface is usually registered as a dynamic type
1100/// within a [`TypeModule`] subclass:
1101///
1102/// ```ignore
1103/// pub struct MyModuleInterface {
1104/// parent: glib::gobject_ffi::GTypeInterface,
1105/// }
1106/// #[glib::object_interface]
1107/// #[object_interface_dynamic]
1108/// unsafe impl ObjectInterface for MyModuleInterface { ... }
1109/// ...
1110/// #[derive(Default)]
1111/// pub struct MyModule;
1112/// ...
1113/// impl TypeModuleImpl for MyModule {
1114/// fn load(&self) -> bool {
1115/// // registers object interfaces as dynamic types.
1116/// let my_module = self.obj();
1117/// let type_module: &glib::TypeModule = my_module.upcast_ref();
1118/// MyModuleInterface::on_implementation_load(type_module)
1119/// }
1120/// ...
1121/// }
1122/// ```
1123///
1124/// Optionally setting `plugin_type` allows to register an object interface as
1125/// a dynamic type within a [`TypePlugin`] subclass that is not a [`TypeModule`]:
1126///
1127/// ```ignore
1128/// pub struct MyPluginInterface {
1129/// parent: glib::gobject_ffi::GTypeInterface,
1130/// }
1131/// #[glib::object_interface]
1132/// #[object_interface_dynamic(plugin_type = MyPlugin)]
1133/// unsafe impl ObjectInterface for MyPluginInterface { ... }
1134/// ...
1135/// #[derive(Default)]
1136/// pub struct MyPlugin;
1137/// ...
1138/// impl TypePluginImpl for MyPlugin {
1139/// fn use_plugin(&self) {
1140/// // register object interfaces as dynamic types.
1141/// let my_plugin = self.obj();
1142/// MyPluginInterface::on_implementation_load(my_plugin.as_ref());
1143/// }
1144/// ...
1145/// }
1146/// ```
1147///
1148/// [`ObjectInterface`]: ../glib/subclass/interface/trait.ObjectInterface.html
1149/// [`TypePlugin`]: ../glib/gobject/type_plugin/struct.TypePlugin.html
1150/// [`TypeModule`]: ../glib/gobject/type_module/struct.TypeModule.html
1151/// [`TypePluginExt::unuse`]: ../glib/gobject/type_plugin/trait.TypePluginExt.html#method.unuse///
1152#[proc_macro_attribute]
1153pub fn object_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
1154 let input = parse_macro_input!(item with object_impl_attributes::Input::parse_interface);
1155 object_impl_attributes::interface::impl_object_interface(input).into()
1156}
1157
1158/// Macro for deriving implementations of [`glib::clone::Downgrade`] and
1159/// [`glib::clone::Upgrade`] traits and a weak type.
1160///
1161/// # Examples
1162///
1163/// ## New Type Idiom
1164///
1165/// ```rust,ignore
1166/// #[derive(glib::Downgrade)]
1167/// pub struct FancyLabel(gtk::Label);
1168///
1169/// impl FancyLabel {
1170/// pub fn new(label: &str) -> Self {
1171/// Self(gtk::LabelBuilder::new().label(label).build())
1172/// }
1173///
1174/// pub fn flip(&self) {
1175/// self.0.set_angle(180.0 - self.0.angle());
1176/// }
1177/// }
1178///
1179/// let fancy_label = FancyLabel::new("Look at me!");
1180/// let button = gtk::ButtonBuilder::new().label("Click me!").build();
1181/// button.connect_clicked(
1182/// clone!(
1183/// #[weak]
1184/// fancy_label,
1185/// move || fancy_label.flip(),
1186/// ),
1187/// );
1188/// ```
1189///
1190/// ## Generic New Type
1191///
1192/// ```rust,ignore
1193/// #[derive(glib::Downgrade)]
1194/// pub struct TypedEntry<T>(gtk::Entry, std::marker::PhantomData<T>);
1195///
1196/// impl<T: ToString + FromStr> for TypedEntry<T> {
1197/// // ...
1198/// }
1199/// ```
1200///
1201/// ## Structures and Enums
1202///
1203/// ```rust,ignore
1204/// #[derive(Clone, glib::Downgrade)]
1205/// pub struct ControlButtons {
1206/// pub up: gtk::Button,
1207/// pub down: gtk::Button,
1208/// pub left: gtk::Button,
1209/// pub right: gtk::Button,
1210/// }
1211///
1212/// #[derive(Clone, glib::Downgrade)]
1213/// pub enum DirectionButton {
1214/// Left(gtk::Button),
1215/// Right(gtk::Button),
1216/// Up(gtk::Button),
1217/// Down(gtk::Button),
1218/// }
1219/// ```
1220///
1221/// [`glib::clone::Downgrade`]: ../glib/clone/trait.Downgrade.html
1222/// [`glib::clone::Upgrade`]: ../glib/clone/trait.Upgrade.html
1223#[proc_macro_derive(Downgrade)]
1224pub fn downgrade(input: TokenStream) -> TokenStream {
1225 let input = parse_macro_input!(input as DeriveInput);
1226 downgrade_derive::impl_downgrade(input)
1227}
1228
1229/// Derive macro for serializing/deserializing custom structs/enums as [`glib::Variant`]s.
1230///
1231/// # Example
1232///
1233/// ```
1234/// use glib::prelude::*;
1235///
1236/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
1237/// struct Foo {
1238/// some_string: String,
1239/// some_int: i32,
1240/// }
1241///
1242/// let v = Foo { some_string: String::from("bar"), some_int: 1 };
1243/// let var = v.to_variant();
1244/// assert_eq!(var.get::<Foo>(), Some(v));
1245/// ```
1246///
1247/// When storing `Vec`s of fixed size types it is a good idea to wrap these in
1248/// `glib::FixedSizeVariantArray` as serialization/deserialization will be more efficient.
1249///
1250/// # Example
1251///
1252/// ```
1253/// use glib::prelude::*;
1254///
1255/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
1256/// struct Foo {
1257/// some_vec: glib::FixedSizeVariantArray<Vec<u32>, u32>,
1258/// some_int: i32,
1259/// }
1260///
1261/// let v = Foo { some_vec: vec![1u32, 2u32].into(), some_int: 1 };
1262/// let var = v.to_variant();
1263/// assert_eq!(var.get::<Foo>(), Some(v));
1264/// ```
1265///
1266/// Enums are serialized as a tuple `(sv)` with the first value as a [kebab case] string for the
1267/// enum variant, or just `s` if this is a C-style enum. Some additional attributes are supported
1268/// for enums:
1269/// - `#[variant_enum(repr)]` to serialize the enum variant as an integer type instead of `s`. The
1270/// `#[repr]` attribute must also be specified on the enum with a sized integer type, and the type
1271/// must implement `Copy`.
1272/// - `#[variant_enum(enum)]` uses [`EnumClass`] to serialize/deserialize as nicks. Meant for use
1273/// with [`glib::Enum`](Enum).
1274/// - `#[variant_enum(flags)]` uses [`FlagsClass`] to serialize/deserialize as nicks. Meant for use
1275/// with [`glib::flags`](macro@flags).
1276/// - `#[variant_enum(enum, repr)]` serializes as `i32`. Meant for use with [`glib::Enum`](Enum).
1277/// The type must also implement `Copy`.
1278/// - `#[variant_enum(flags, repr)]` serializes as `u32`. Meant for use with
1279/// [`glib::flags`](macro@flags).
1280///
1281/// # Example
1282///
1283/// ```
1284/// use glib::prelude::*;
1285///
1286/// #[derive(Debug, PartialEq, Eq, glib::Variant)]
1287/// enum Foo {
1288/// MyA,
1289/// MyB(i32),
1290/// MyC { some_int: u32, some_string: String }
1291/// }
1292///
1293/// let v = Foo::MyC { some_int: 1, some_string: String::from("bar") };
1294/// let var = v.to_variant();
1295/// assert_eq!(var.child_value(0).str(), Some("my-c"));
1296/// assert_eq!(var.get::<Foo>(), Some(v));
1297///
1298/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Variant)]
1299/// #[variant_enum(repr)]
1300/// #[repr(u8)]
1301/// enum Bar {
1302/// A,
1303/// B = 3,
1304/// C = 7
1305/// }
1306///
1307/// let v = Bar::B;
1308/// let var = v.to_variant();
1309/// assert_eq!(var.get::<u8>(), Some(3));
1310/// assert_eq!(var.get::<Bar>(), Some(v));
1311///
1312/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum, glib::Variant)]
1313/// #[variant_enum(enum)]
1314/// #[enum_type(name = "MyEnum")]
1315/// enum MyEnum {
1316/// Val,
1317/// #[enum_value(name = "My Val")]
1318/// ValWithCustomName,
1319/// #[enum_value(name = "My Other Val", nick = "other")]
1320/// ValWithCustomNameAndNick,
1321/// }
1322///
1323/// let v = MyEnum::ValWithCustomNameAndNick;
1324/// let var = v.to_variant();
1325/// assert_eq!(var.str(), Some("other"));
1326/// assert_eq!(var.get::<MyEnum>(), Some(v));
1327/// ```
1328///
1329/// [`glib::Variant`]: ../glib/variant/struct.Variant.html
1330/// [`EnumClass`]: ../glib/struct.EnumClass.html
1331/// [`FlagsClass`]: ../glib/struct.FlagsClass.html
1332/// [kebab case]: https://docs.rs/heck/0.4.0/heck/trait.ToKebabCase.html
1333#[proc_macro_derive(Variant, attributes(variant_enum))]
1334pub fn variant_derive(input: TokenStream) -> TokenStream {
1335 let input = parse_macro_input!(input as DeriveInput);
1336 variant_derive::impl_variant(input)
1337 .unwrap_or_else(syn::Error::into_compile_error)
1338 .into()
1339}
1340#[proc_macro]
1341pub fn cstr_bytes(item: TokenStream) -> TokenStream {
1342 syn::parse::Parser::parse2(
1343 |stream: syn::parse::ParseStream<'_>| {
1344 let literal = stream.parse::<syn::LitStr>()?;
1345 stream.parse::<syn::parse::Nothing>()?;
1346 let bytes = std::ffi::CString::new(literal.value())
1347 .map_err(|e| syn::Error::new_spanned(&literal, format!("{e}")))?
1348 .into_bytes_with_nul();
1349 let bytes = proc_macro2::Literal::byte_string(&bytes);
1350 Ok(quote::quote! { #bytes }.into())
1351 },
1352 item.into(),
1353 )
1354 .unwrap_or_else(|e| e.into_compile_error().into())
1355}
1356
1357/// This macro enables you to derive object properties in a quick way.
1358///
1359/// # Supported `#[property]` attributes
1360/// | Attribute | Description | Default | Example |
1361/// | --- | --- | --- | --- |
1362/// | `name = "literal"` | The name of the property | field ident where `_` (leading and trailing `_` are trimmed) is replaced into `-` | `#[property(name = "prop-name")]` |
1363/// | `type = expr` | The type of the property | inferred | `#[property(type = i32)]` |
1364/// | `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)]` |
1365/// | `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\| {})]` |
1366/// | `override_class = expr` | The type of class of which to override the property from | | `#[property(override_class = SomeClass)]` |
1367/// | `override_interface = expr` | The type of interface of which to override the property from | | `#[property(override_interface = SomeInterface)]` |
1368/// | `nullable` | Whether to use `Option<T>` in the generated setter method | | `#[property(nullable)]` |
1369/// | `member = ident` | Field of the nested type where property is retrieved and set | | `#[property(member = author)]` |
1370/// | `construct` | Specify that the property is construct property. Ensures that the property is always set during construction (if not explicitly then the default value is used). The use of a custom internal setter is supported. | | `#[property(get, construct)]` or `#[property(get, set = set_prop, construct)]` |
1371/// | `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)]` |
1372/// | `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. |
1373/// | `default` | Sets the `default_value` field of the Param Spec builder | | `#[property(default = 1)]` |
1374/// | `<optional-pspec-builder-fields> = expr` | Used to add optional Param Spec builder fields | | `#[property(minimum = 0)` , `#[property(minimum = 0, maximum = 1)]`, etc. |
1375/// | `<optional-pspec-builder-fields>` | Used to add optional Param Spec builder fields | | `#[property(explicit_notify)]` , `#[property(construct_only)]`, etc. |
1376///
1377/// ## Using Rust keywords as property names
1378/// 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.
1379/// 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.
1380///
1381/// # Generated methods
1382/// The following methods are generated on the wrapper type specified on `#[properties(wrapper_type = ...)]`:
1383/// * `$property()`, when the property is readable
1384/// * `set_$property()`, when the property is writable and not construct-only
1385/// * `connect_$property_notify()`
1386/// * `notify_$property()`
1387///
1388/// # Documentation
1389///
1390/// Doc comments preceding a `#[property]` attribute will be copied to the generated getter and setter methods. You can specify different comments by the getter and setter by using `# Getter` and `# Setter` headings. The text under the header will be copied to the respective method.
1391///
1392/// ## Extension trait
1393/// You can choose to move the method definitions to a trait by using `#[properties(wrapper_type = super::MyType, ext_trait = MyTypePropertiesExt)]`.
1394/// The trait name is optional, and defaults to `MyTypePropertiesExt`, where `MyType` is extracted from the wrapper type.
1395/// Note: The trait is defined in the same module where the `#[derive(Properties)]` call happens, and is implemented on the wrapper type.
1396///
1397/// Notice: You can't reimplement the generated methods on the wrapper type, unless you move them to a trait.
1398/// You can change the behavior of the generated getter/setter methods by using a custom internal getter/setter.
1399///
1400/// # Internal getters and setters
1401/// By default, they are generated for you. However, you can use a custom getter/setter
1402/// by assigning an expression to `get`/`set` `#[property]` attributes: `#[property(get = |_| 2, set)]` or `#[property(get, set = custom_setter_func)]`.
1403///
1404/// # Supported types
1405/// Every type implementing the trait [`Property`] is supported.
1406/// The type `Option<T>` is supported as a property only if `Option<T>` implements [`ToValueOptional`].
1407/// Optional types also require the `nullable` attribute: without it, the generated setter on the wrapper type
1408/// will take `T` instead of `Option<T>`, preventing the user from ever calling the setter with a `None` value.
1409///
1410/// Notice: For enums that derive [`Enum`] or are C-style enums, you must explicitly specify the
1411/// default value of the enum using the `builder` parameter in the `#[property]` attribute.
1412///
1413/// ## Adding support for custom types
1414/// ### Types wrapping an existing <code>T: [ToValue] + [HasParamSpec]</code>
1415/// If you have declared a newtype as
1416/// ```rust
1417/// struct MyInt(i32);
1418/// ```
1419/// you can use it as a property by deriving [`ValueDelegate`].
1420///
1421/// ### Types with inner mutability
1422/// The trait [`Property`] must be implemented.
1423/// The traits [`PropertyGet`] and [`PropertySet`] should be implemented to enable the Properties macro
1424/// to generate a default internal getter/setter.
1425/// If possible, implementing [`PropertySetNested`] is preferred over `PropertySet`, because it
1426/// enables this macro to access the contained type and provide access to its fields,
1427/// using the `member = $structfield` syntax.
1428///
1429/// ### Types without [`HasParamSpec`][HasParamSpec]
1430/// If you have encountered a type <code>T: [ToValue]</code>, inside the gtk-rs crate, which doesn't implement [`HasParamSpec`][HasParamSpec],
1431/// then it's a bug and you should report it.
1432/// If you need to support a `ToValue` type with a [`ParamSpec`] not provided by gtk-rs, then you need to
1433/// implement `HasParamSpec` on that type.
1434///
1435/// # Example
1436/// ```
1437/// use std::cell::{Cell, RefCell};
1438/// use glib::prelude::*;
1439/// use glib::subclass::prelude::*;
1440/// use glib_macros::Properties;
1441///
1442/// #[derive(Default, Clone)]
1443/// struct Author {
1444/// name: String,
1445/// nick: String,
1446/// }
1447///
1448/// #[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum, Default)]
1449/// #[enum_type(name = "MyEnum")]
1450/// pub enum MyEnum {
1451/// #[default]
1452/// Val,
1453/// OtherVal
1454/// }
1455///
1456/// pub mod imp {
1457/// use std::rc::Rc;
1458///
1459/// use super::*;
1460///
1461/// #[derive(Properties, Default)]
1462/// #[properties(wrapper_type = super::Foo)]
1463/// pub struct Foo {
1464/// #[property(get, set = Self::set_fizz)]
1465/// fizz: RefCell<String>,
1466/// /// The author's name
1467/// #[property(name = "author-name", get, set, type = String, member = name)]
1468/// /// The author's childhood nickname
1469/// #[property(name = "author-nick", get, set, type = String, member = nick)]
1470/// author: RefCell<Author>,
1471/// #[property(get, set, explicit_notify, lax_validation)]
1472/// custom_flags: RefCell<String>,
1473/// #[property(get, set, minimum = 0, maximum = 3)]
1474/// numeric_builder: RefCell<u32>,
1475/// #[property(get, set, builder('c'))]
1476/// builder_with_required_param: RefCell<char>,
1477/// #[property(get, set, nullable)]
1478/// optional: RefCell<Option<String>>,
1479/// #[property(get, set)]
1480/// smart_pointer: Rc<RefCell<String>>,
1481/// #[property(get, set, builder(MyEnum::Val))]
1482/// my_enum: Cell<MyEnum>,
1483/// /// # Getter
1484/// ///
1485/// /// Get the value of the property `extra_comments`
1486/// ///
1487/// /// # Setter
1488/// ///
1489/// /// This is the comment for the setter of the `extra_comments` field.
1490/// #[property(get, set)]
1491/// extra_comments: RefCell<bool>,
1492/// }
1493///
1494/// #[glib::derived_properties]
1495/// impl ObjectImpl for Foo {}
1496///
1497/// #[glib::object_subclass]
1498/// impl ObjectSubclass for Foo {
1499/// const NAME: &'static str = "MyFoo";
1500/// type Type = super::Foo;
1501/// }
1502///
1503/// impl Foo {
1504/// fn set_fizz(&self, value: String) {
1505/// *self.fizz.borrow_mut() = format!("custom set: {}", value);
1506/// }
1507/// }
1508/// }
1509///
1510/// glib::wrapper! {
1511/// pub struct Foo(ObjectSubclass<imp::Foo>);
1512/// }
1513///
1514/// fn main() {
1515/// let myfoo: Foo = glib::object::Object::new();
1516///
1517/// myfoo.set_fizz("test value");
1518/// assert_eq!(myfoo.fizz(), "custom set: test value".to_string());
1519/// }
1520/// ```
1521///
1522/// [`Property`]: ../glib/property/trait.Property.html
1523/// [`PropertyGet`]: ../glib/property/trait.PropertyGet.html
1524/// [`PropertyGet::get`]: ../glib/property/trait.PropertyGet.html#tymethod.get
1525/// [`PropertySet`]: ../glib/property/trait.PropertySet.html
1526/// [`PropertySet::set`]: ../glib/property/trait.PropertySet.html#tymethod.set
1527/// [`PropertySetNested`]: ../glib/property/trait.PropertySetNested.html
1528/// [`ObjectExt::property`]: ../glib/object/trait.ObjectExt.html#tymethod.property
1529/// [HasParamSpec]: ../glib/trait.HasParamSpec.html
1530/// [`ParamSpec`]: ../glib/struct.ParamSpec.html
1531/// [`ToValueOptional`]: ../glib/value/trait.ToValueOptional.html
1532/// [ToValue]: ../glib/value/trait.ToValue.html
1533#[allow(clippy::needless_doctest_main)]
1534#[proc_macro_derive(Properties, attributes(properties, property))]
1535pub fn derive_props(input: TokenStream) -> TokenStream {
1536 let input = parse_macro_input!(input as properties::PropsMacroInput);
1537 properties::impl_derive_props(input)
1538}
1539
1540/// When applied to `ObjectImpl`
1541/// ```ignore
1542/// #[glib::derived_properties]
1543/// impl ObjectImpl for CustomObject
1544/// ```
1545/// this macro generates
1546/// ```ignore
1547/// impl ObjectImpl for CustomObject {
1548/// fn properties() -> &'static [glib::ParamSpec] {
1549/// Self::derived_properties()
1550/// }
1551/// fn set_property(&self, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
1552/// self.derived_set_property(id, value, pspec)
1553/// }
1554/// fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
1555/// self.derived_property(id, pspec)
1556/// }
1557/// }
1558/// ```
1559#[proc_macro_attribute]
1560pub fn derived_properties(_attr: TokenStream, item: TokenStream) -> TokenStream {
1561 syn::parse::<syn::ItemImpl>(item)
1562 .map_err(|_| {
1563 syn::Error::new(
1564 Span::call_site(),
1565 derived_properties_attribute::WRONG_PLACE_MSG,
1566 )
1567 })
1568 .and_then(|input| derived_properties_attribute::impl_derived_properties(&input))
1569 .unwrap_or_else(syn::Error::into_compile_error)
1570 .into()
1571}
1572
1573/// # Example
1574/// ```
1575/// use glib::prelude::*;
1576/// use glib::ValueDelegate;
1577///
1578/// #[derive(ValueDelegate, Debug, PartialEq)]
1579/// struct MyInt(i32);
1580///
1581/// let myv = MyInt(2);
1582/// let convertedv = myv.to_value();
1583/// assert_eq!(convertedv.get::<MyInt>(), Ok(myv));
1584///
1585///
1586/// #[derive(ValueDelegate, Debug, PartialEq)]
1587/// #[value_delegate(from = u32)]
1588/// enum MyEnum {
1589/// Zero,
1590/// NotZero(u32)
1591/// }
1592///
1593/// impl From<u32> for MyEnum {
1594/// fn from(v: u32) -> Self {
1595/// match v {
1596/// 0 => MyEnum::Zero,
1597/// x => MyEnum::NotZero(x)
1598/// }
1599/// }
1600/// }
1601/// impl<'a> From<&'a MyEnum> for u32 {
1602/// fn from(v: &'a MyEnum) -> Self {
1603/// match v {
1604/// MyEnum::Zero => 0,
1605/// MyEnum::NotZero(x) => *x
1606/// }
1607/// }
1608/// }
1609/// impl From<MyEnum> for u32 {
1610/// fn from(v: MyEnum) -> Self {
1611/// match v {
1612/// MyEnum::Zero => 0,
1613/// MyEnum::NotZero(x) => x
1614/// }
1615/// }
1616/// }
1617///
1618/// let myv = MyEnum::NotZero(34);
1619/// let convertedv = myv.to_value();
1620/// assert_eq!(convertedv.get::<MyEnum>(), Ok(myv));
1621///
1622///
1623/// // If you want your type to be usable inside an `Option`, you can derive `ToValueOptional`
1624/// // by adding `nullable` as follows
1625/// #[derive(ValueDelegate, Debug, PartialEq)]
1626/// #[value_delegate(nullable)]
1627/// struct MyString(String);
1628///
1629/// let myv = Some(MyString("Hello world".to_string()));
1630/// let convertedv = myv.to_value();
1631/// assert_eq!(convertedv.get::<Option<MyString>>(), Ok(myv));
1632/// let convertedv = None::<MyString>.to_value();
1633/// assert_eq!(convertedv.get::<Option<MyString>>(), Ok(None::<MyString>));
1634/// ```
1635#[proc_macro_derive(ValueDelegate, attributes(value_delegate))]
1636pub fn derive_value_delegate(input: TokenStream) -> TokenStream {
1637 let input = parse_macro_input!(input as value_delegate_derive::ValueDelegateInput);
1638 value_delegate_derive::impl_value_delegate(input).unwrap()
1639}
1640
1641/// An attribute macro for writing asynchronous test functions.
1642///
1643/// This macro is designed to wrap an asynchronous test function and ensure that
1644/// it runs within a `glib::MainContext`. It helps in writing async tests that
1645/// require the use of an event loop for the asynchronous execution.
1646///
1647/// # Example
1648///
1649/// ```
1650/// #[glib::async_test]
1651/// async fn my_async_test() {
1652/// // Test code that runs asynchronously
1653/// }
1654/// ```
1655#[proc_macro_attribute]
1656pub fn async_test(args: TokenStream, item: TokenStream) -> TokenStream {
1657 async_test::async_test(args, item)
1658}