glib

Derive Macro Enum

Source
#[derive(Enum)]
{
    // Attributes available to this derive:
    #[enum_type]
    #[enum_dynamic]
    #[enum_value]
}
Expand description

Derive macro to register a Rust enum in the GLib type system and derive the glib::Value traits.

§Example

use glib::prelude::*;
use glib::subclass::prelude::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MyEnum")]
enum MyEnum {
    Val,
    #[enum_value(name = "My Val")]
    ValWithCustomName,
    #[enum_value(name = "My Other Val", nick = "other")]
    ValWithCustomNameAndNick,
}

An enum can be registered as a dynamic type by setting the derive macro helper attribute enum_dynamic:

use glib::prelude::*;
use glib::subclass::prelude::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MyEnum")]
#[enum_dynamic]
enum MyEnum {
    ...
}

As a dynamic type, an enum must be explicitly registered when the system loads the implementation (see TypePlugin and TypeModule). Therefore, whereas an enum can be registered only once as a static type, it can be registered several times as a dynamic type.

An enum registered as a dynamic type is never unregistered. The system calls TypePluginExt::unuse to unload the implementation. If the TypePlugin subclass is a TypeModule, the enum registered as a dynamic type is marked as unloaded and must be registered again when the module is reloaded.

The derive macro helper attribute enum_dynamic provides two behaviors when registering an enum as a dynamic type:

  • lazy registration: by default an enum is registered as a dynamic type when the system loads the implementation (e.g. when the module is loaded). Optionally setting lazy_registration to true postpones registration on the first use (when static_type() is called for the first time):
#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MyEnum")]
#[enum_dynamic(lazy_registration = true)]
enum MyEnum {
    ...
}
  • registration within TypeModule subclass or within TypePlugin subclass: an enum is usually registered as a dynamic type within a TypeModule subclass:
#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MyModuleEnum")]
#[enum_dynamic]
enum MyModuleEnum {
    ...
}
...
#[derive(Default)]
pub struct MyModule;
...
impl TypeModuleImpl for MyModule {
    fn load(&self) -> bool {
        // registers enums as dynamic types.
        let my_module = self.obj();
        let type_module: &glib::TypeModule = my_module.upcast_ref();
        MyModuleEnum::on_implementation_load(type_module)
    }
    ...
}

Optionally setting plugin_type allows to register an enum as a dynamic type within a TypePlugin subclass that is not a TypeModule:

#[derive(Debug, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MyPluginEnum")]
#[enum_dynamic(plugin_type = MyPlugin)]
enum MyPluginEnum {
    ...
}
...
#[derive(Default)]
pub struct MyPlugin;
...
impl TypePluginImpl for MyPlugin {
    fn use_plugin(&self) {
        // register enums as dynamic types.
        let my_plugin = self.obj();
        MyPluginEnum::on_implementation_load(my_plugin.as_ref());
    }
    ...
}