pub const ext = @import("ext.zig");
const gudev = @This();

const std = @import("std");
const compat = @import("compat");
const gobject = @import("gobject2");
const glib = @import("glib2");
/// Corresponds to the standard `dev_t` type as defined by POSIX (Until
/// bug 584517 is resolved this work-around is needed).
pub const DeviceNumber = u64;

/// `gudev.Client` is used to query information about devices on a Linux
/// system from the Linux kernel and the udev device
/// manager.
///
/// Device information is retrieved from the kernel (through the
/// <literal>sysfs</literal> filesystem) and the udev daemon (through a
/// <literal>tmpfs</literal> filesystem) and presented through
/// `gudev.Device` objects. This means that no blocking IO ever happens
/// (in both cases, we are essentially just reading data from kernel
/// memory) and as such there are no asynchronous versions of the
/// provided methods.
///
/// To get `gudev.Device` objects, use
/// `gudev.Client.queryBySubsystem`,
/// `gudev.Client.queryByDeviceNumber`,
/// `gudev.Client.queryByDeviceFile`,
/// `gudev.Client.queryBySysfsPath`,
/// `gudev.Client.queryBySubsystemAndName`
/// or the `gudev.Enumerator` type.
///
/// To listen to uevents, connect to the `gudev.Client.signals.uevent` signal.
pub const Client = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gudev.ClientClass;
    f_parent: gobject.Object,
    f_priv: ?*gudev.ClientPrivate,

    pub const virtual_methods = struct {
        /// Signal class handler for the `gudev.Client.signals.uevent` signal.
        pub const uevent = struct {
            pub fn call(p_class: anytype, p_client: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_action: [*:0]const u8, p_device: *gudev.Device) void {
                return gobject.ext.as(Client.Class, p_class).f_uevent.?(gobject.ext.as(Client, p_client), p_action, p_device);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_client: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_action: [*:0]const u8, p_device: *gudev.Device) callconv(.c) void) void {
                gobject.ext.as(Client.Class, p_class).f_uevent = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The subsystems to listen for uevents on.
        ///
        /// To listen for only a specific DEVTYPE for a given SUBSYSTEM, use
        /// "subsystem/devtype". For example, to only listen for uevents
        /// where SUBSYSTEM is usb and DEVTYPE is usb_interface, use
        /// "usb/usb_interface".
        ///
        /// If this property is `NULL`, then no events will be reported. If
        /// it's the empty array, events from all subsystems will be
        /// reported.
        pub const subsystems = struct {
            pub const name = "subsystems";

            pub const Type = ?[*][*:0]u8;
        };
    };

    pub const signals = struct {
        /// Emitted when `client` receives an uevent.
        ///
        /// Note that while you'll have access to all the device's properties and attributes
        /// for the majority of actions, only the sysfs path will be available when the device
        /// is removed.
        ///
        /// Also note that the action is an arbitrary string, controlled by device drivers. Other
        /// values than those listed is possible, but unlikely.
        ///
        /// This signal is emitted in the
        /// <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
        /// of the thread that `client` was created in.
        pub const uevent = struct {
            pub const name = "uevent";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_action: [*:0]u8, p_device: *gudev.Device, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Client, p_instance))),
                    gobject.signalLookup("uevent", Client.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Constructs a `gudev.Client` object that can be used to query
    /// information about devices. Connect to the `gudev.Client.signals.uevent`
    /// signal to listen for uevents. Note that signals are emitted in the
    /// <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
    /// of the thread that you call this constructor from.
    extern fn g_udev_client_new(p_subsystems: ?[*]const [*:0]const u8) *gudev.Client;
    pub const new = g_udev_client_new;

    /// Looks up a device for a device file.
    extern fn g_udev_client_query_by_device_file(p_client: *Client, p_device_file: [*:0]const u8) ?*gudev.Device;
    pub const queryByDeviceFile = g_udev_client_query_by_device_file;

    /// Looks up a device for a type and device number.
    extern fn g_udev_client_query_by_device_number(p_client: *Client, p_type: gudev.DeviceType, p_number: gudev.DeviceNumber) ?*gudev.Device;
    pub const queryByDeviceNumber = g_udev_client_query_by_device_number;

    /// Gets all devices belonging to `subsystem`.
    extern fn g_udev_client_query_by_subsystem(p_client: *Client, p_subsystem: ?[*:0]const u8) ?*glib.List;
    pub const queryBySubsystem = g_udev_client_query_by_subsystem;

    /// Looks up a device for a subsystem and name.
    extern fn g_udev_client_query_by_subsystem_and_name(p_client: *Client, p_subsystem: [*:0]const u8, p_name: [*:0]const u8) ?*gudev.Device;
    pub const queryBySubsystemAndName = g_udev_client_query_by_subsystem_and_name;

    /// Looks up a device for a sysfs path.
    extern fn g_udev_client_query_by_sysfs_path(p_client: *Client, p_sysfs_path: [*:0]const u8) ?*gudev.Device;
    pub const queryBySysfsPath = g_udev_client_query_by_sysfs_path;

    extern fn g_udev_client_get_type() usize;
    pub const getGObjectType = g_udev_client_get_type;

    extern fn g_object_ref(p_self: *gudev.Client) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gudev.Client) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Client, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gudev.Device` class is used to get information about a specific
/// device. Note that you cannot instantiate a `gudev.Device` object
/// yourself. Instead you must use `gudev.Client` to obtain `gudev.Device`
/// objects.
///
/// To get basic information about a device, use
/// `gudev.Device.getSubsystem`, `gudev.Device.getDevtype`,
/// `gudev.Device.getName`, `gudev.Device.getNumber`,
/// `gudev.Device.getSysfsPath`, `gudev.Device.getDriver`,
/// `gudev.Device.getAction`, `gudev.Device.getSeqnum`,
/// `gudev.Device.getDeviceType`, `gudev.Device.getDeviceNumber`,
/// `gudev.Device.getDeviceFile`,
/// `gudev.Device.getDeviceFileSymlinks`.
///
/// To navigate the device tree, use `gudev.Device.getParent` and
/// `gudev.Device.getParentWithSubsystem`.
///
/// To access udev properties for the device, use
/// `gudev.Device.getPropertyKeys`,
/// `gudev.Device.hasProperty`,
/// `gudev.Device.getProperty`,
/// `gudev.Device.getPropertyAsInt`,
/// `gudev.Device.getPropertyAsUint64`,
/// `gudev.Device.getPropertyAsDouble`,
/// `gudev.Device.getPropertyAsBoolean` and
/// `gudev.Device.getPropertyAsStrv`.
///
/// To access sysfs attributes for the device, use
/// `gudev.Device.getSysfsAttrKeys`,
/// `gudev.Device.hasSysfsAttr`,
/// `gudev.Device.getSysfsAttr`,
/// `gudev.Device.getSysfsAttrAsInt`,
/// `gudev.Device.getSysfsAttrAsUint64`,
/// `gudev.Device.getSysfsAttrAsDouble`,
/// `gudev.Device.getSysfsAttrAsBoolean` and
/// `gudev.Device.getSysfsAttrAsStrv`.
///
/// Note that all getters on `gudev.Device` are non-reffing – returned
/// values are owned by the object, should not be freed and are only
/// valid as long as the object is alive.
///
/// By design, `gudev.Device` will not react to changes for a device – it
/// only contains a snapshot of information when the `gudev.Device`
/// object was created. To work with changes, you typically connect to
/// the `gudev.Client.signals.uevent` signal on a `gudev.Client` and get a new
/// `gudev.Device` whenever an event happens.
pub const Device = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gudev.DeviceClass;
    f_parent: gobject.Object,
    f_priv: ?*gudev.DevicePrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the most recent action (e.g. "add", "remove", "change", etc.) for `device`.
    extern fn g_udev_device_get_action(p_device: *Device) [*:0]const u8;
    pub const getAction = g_udev_device_get_action;

    /// Gets all current tags for `device`.
    ///
    /// https://www.freedesktop.org/software/systemd/man/udev_device_has_current_tag.html
    extern fn g_udev_device_get_current_tags(p_device: *Device) [*]const [*:0]const u8;
    pub const getCurrentTags = g_udev_device_get_current_tags;

    /// Gets the device file for `device`.
    extern fn g_udev_device_get_device_file(p_device: *Device) ?[*:0]const u8;
    pub const getDeviceFile = g_udev_device_get_device_file;

    /// Gets a list of symlinks (in <literal>/dev</literal>) that points to
    /// the device file for `device`.
    extern fn g_udev_device_get_device_file_symlinks(p_device: *Device) [*]const [*:0]const u8;
    pub const getDeviceFileSymlinks = g_udev_device_get_device_file_symlinks;

    /// Gets the device number, if any, for `device`.
    extern fn g_udev_device_get_device_number(p_device: *Device) gudev.DeviceNumber;
    pub const getDeviceNumber = g_udev_device_get_device_number;

    /// Gets the type of the device file, if any, for `device`.
    extern fn g_udev_device_get_device_type(p_device: *Device) gudev.DeviceType;
    pub const getDeviceType = g_udev_device_get_device_type;

    /// Gets the device type for `device`.
    extern fn g_udev_device_get_devtype(p_device: *Device) [*:0]const u8;
    pub const getDevtype = g_udev_device_get_devtype;

    /// Gets the name of the driver used for `device`.
    extern fn g_udev_device_get_driver(p_device: *Device) ?[*:0]const u8;
    pub const getDriver = g_udev_device_get_driver;

    /// Gets whether `device` has been initialized.
    extern fn g_udev_device_get_is_initialized(p_device: *Device) c_int;
    pub const getIsInitialized = g_udev_device_get_is_initialized;

    /// Gets the name of `device`, e.g. "sda3".
    extern fn g_udev_device_get_name(p_device: *Device) [*:0]const u8;
    pub const getName = g_udev_device_get_name;

    /// Gets the number of `device`, e.g. "3" if `gudev.Device.getName` returns "sda3".
    extern fn g_udev_device_get_number(p_device: *Device) [*:0]const u8;
    pub const getNumber = g_udev_device_get_number;

    /// Gets the immediate parent of `device`, if any.
    extern fn g_udev_device_get_parent(p_device: *Device) ?*gudev.Device;
    pub const getParent = g_udev_device_get_parent;

    /// Walks up the chain of parents of `device` and returns the first
    /// device encountered where `subsystem` and `devtype` matches, if any.
    extern fn g_udev_device_get_parent_with_subsystem(p_device: *Device, p_subsystem: [*:0]const u8, p_devtype: ?[*:0]const u8) ?*gudev.Device;
    pub const getParentWithSubsystem = g_udev_device_get_parent_with_subsystem;

    /// Look up the value for `key` on `device`.
    extern fn g_udev_device_get_property(p_device: *Device, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getProperty = g_udev_device_get_property;

    /// Look up the value for `key` on `device` and convert it to an
    /// boolean. This is done by doing a case-insensitive string comparison
    /// on the string value against "1" and "true".
    extern fn g_udev_device_get_property_as_boolean(p_device: *Device, p_key: [*:0]const u8) c_int;
    pub const getPropertyAsBoolean = g_udev_device_get_property_as_boolean;

    /// Look up the value for `key` on `device` and convert it to a double
    /// precision floating point number using `glib.asciiStrtod`.
    extern fn g_udev_device_get_property_as_double(p_device: *Device, p_key: [*:0]const u8) f64;
    pub const getPropertyAsDouble = g_udev_device_get_property_as_double;

    /// Look up the value for `key` on `device` and convert it to an integer
    /// using `strtol`.
    extern fn g_udev_device_get_property_as_int(p_device: *Device, p_key: [*:0]const u8) c_int;
    pub const getPropertyAsInt = g_udev_device_get_property_as_int;

    /// Look up the value for `key` on `device` and return the result of
    /// splitting it into non-empty tokens split at white space (only space
    /// (' '), form-feed ('\f'), newline ('\n'), carriage return ('\r'),
    /// horizontal tab ('\t'), and vertical tab ('\v') are considered; the
    /// locale is not taken into account).
    extern fn g_udev_device_get_property_as_strv(p_device: *Device, p_key: [*:0]const u8) ?[*]const [*:0]const u8;
    pub const getPropertyAsStrv = g_udev_device_get_property_as_strv;

    /// Look up the value for `key` on `device` and convert it to an unsigned
    /// 64-bit integer using `glib.asciiStrtoull`.
    extern fn g_udev_device_get_property_as_uint64(p_device: *Device, p_key: [*:0]const u8) u64;
    pub const getPropertyAsUint64 = g_udev_device_get_property_as_uint64;

    /// Gets all keys for properties on `device`.
    extern fn g_udev_device_get_property_keys(p_device: *Device) [*]const [*:0]const u8;
    pub const getPropertyKeys = g_udev_device_get_property_keys;

    /// Gets the most recent sequence number for `device`.
    extern fn g_udev_device_get_seqnum(p_device: *Device) u64;
    pub const getSeqnum = g_udev_device_get_seqnum;

    /// Gets the subsystem for `device`.
    extern fn g_udev_device_get_subsystem(p_device: *Device) [*:0]const u8;
    pub const getSubsystem = g_udev_device_get_subsystem;

    /// Look up the sysfs attribute with `name` on `device`. The retrieved value
    /// is cached in the device. Repeated calls will return the same value and
    /// not open the attribute again, unless updated through one of the
    /// "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr(p_device: *Device, p_name: [*:0]const u8) ?[*:0]const u8;
    pub const getSysfsAttr = g_udev_device_get_sysfs_attr;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an
    /// boolean. This is done by doing a case-insensitive string comparison
    /// on the string value against "1", "true", "Y" and "y". The retrieved value is
    /// cached in the device. Repeated calls will return the same value and
    /// not open the attribute again, unless updated through one of the
    /// "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr_as_boolean(p_device: *Device, p_name: [*:0]const u8) c_int;
    pub const getSysfsAttrAsBoolean = g_udev_device_get_sysfs_attr_as_boolean;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an
    /// boolean. This is done by doing a case-insensitive string comparison
    /// on the string value against "1", "true", "Y" and "y". This function does
    /// blocking I/O, and updates the sysfs attributes cache.
    ///
    /// Before version 238 the uncached getters would not strip trailing newlines.
    extern fn g_udev_device_get_sysfs_attr_as_boolean_uncached(p_device: *Device, p_name: [*:0]const u8) c_int;
    pub const getSysfsAttrAsBooleanUncached = g_udev_device_get_sysfs_attr_as_boolean_uncached;

    /// Look up the sysfs attribute with `name` on `device` and convert it to a double
    /// precision floating point number using `glib.asciiStrtod`. The retrieved value is cached
    /// in the device. Repeated calls will return the same value and not open the
    /// attribute again, unless updated through one of the "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr_as_double(p_device: *Device, p_name: [*:0]const u8) f64;
    pub const getSysfsAttrAsDouble = g_udev_device_get_sysfs_attr_as_double;

    /// Look up the sysfs attribute with `name` on `device` and convert it to a double
    /// precision floating point number using `glib.asciiStrtod`. This function does blocking
    /// I/O, and updates the sysfs attributes cache.
    ///
    /// Before version 238 the uncached getters would not strip trailing newlines.
    extern fn g_udev_device_get_sysfs_attr_as_double_uncached(p_device: *Device, p_name: [*:0]const u8) f64;
    pub const getSysfsAttrAsDoubleUncached = g_udev_device_get_sysfs_attr_as_double_uncached;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an integer
    /// using `strtol`. The retrieved value is cached in the device. Repeated calls
    /// will return the same value and not open the attribute again, unless updated
    /// through one of the "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr_as_int(p_device: *Device, p_name: [*:0]const u8) c_int;
    pub const getSysfsAttrAsInt = g_udev_device_get_sysfs_attr_as_int;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an integer
    /// using `strtol`. This function does blocking I/O, and updates the sysfs
    /// attributes cache.
    ///
    /// Before version 238 the uncached getters would not strip trailing newlines.
    extern fn g_udev_device_get_sysfs_attr_as_int_uncached(p_device: *Device, p_name: [*:0]const u8) c_int;
    pub const getSysfsAttrAsIntUncached = g_udev_device_get_sysfs_attr_as_int_uncached;

    /// Look up the sysfs attribute with `name` on `device` and return the result of
    /// splitting it into non-empty tokens split at white space (only space (' '),
    /// form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
    /// tab ('\t'), and vertical tab ('\v') are considered; the locale is
    /// not taken into account).
    ///
    /// The retrieved value is cached in the device. Repeated calls will return
    /// the same value and not open the attribute again, unless updated through
    /// one of the "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr_as_strv(p_device: *Device, p_name: [*:0]const u8) ?[*]const [*:0]const u8;
    pub const getSysfsAttrAsStrv = g_udev_device_get_sysfs_attr_as_strv;

    /// Look up the sysfs attribute with `name` on `device` and return the result of
    /// splitting it into non-empty tokens split at white space (only space (' '),
    /// form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
    /// tab ('\t'), and vertical tab ('\v') are considered; the locale is
    /// not taken into account).
    ///
    /// This function does blocking I/O, and updates the sysfs attributes cache.
    extern fn g_udev_device_get_sysfs_attr_as_strv_uncached(p_device: *Device, p_name: [*:0]const u8) ?[*]const [*:0]const u8;
    pub const getSysfsAttrAsStrvUncached = g_udev_device_get_sysfs_attr_as_strv_uncached;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an unsigned
    /// 64-bit integer using `glib.asciiStrtoull`. The retrieved value is cached in the
    /// device. Repeated calls will return the same value and not open the attribute
    /// again, unless updated through one of the "uncached" functions.
    extern fn g_udev_device_get_sysfs_attr_as_uint64(p_device: *Device, p_name: [*:0]const u8) u64;
    pub const getSysfsAttrAsUint64 = g_udev_device_get_sysfs_attr_as_uint64;

    /// Look up the sysfs attribute with `name` on `device` and convert it to an unsigned
    /// 64-bit integer using `glib.asciiStrtoull`. This function does blocking I/O, and
    /// updates the sysfs attributes cache.
    ///
    /// Before version 238 the uncached getters would not strip trailing newlines.
    extern fn g_udev_device_get_sysfs_attr_as_uint64_uncached(p_device: *Device, p_name: [*:0]const u8) u64;
    pub const getSysfsAttrAsUint64Uncached = g_udev_device_get_sysfs_attr_as_uint64_uncached;

    /// Gets all keys for sysfs attributes on `device`.
    extern fn g_udev_device_get_sysfs_attr_keys(p_device: *Device) [*]const [*:0]const u8;
    pub const getSysfsAttrKeys = g_udev_device_get_sysfs_attr_keys;

    /// Look up the sysfs attribute with `name` on `device`. This function does
    /// blocking I/O, and updates the sysfs attributes cache.
    ///
    /// Before version 238 the uncached getters would not strip trailing newlines.
    extern fn g_udev_device_get_sysfs_attr_uncached(p_device: *Device, p_name: [*:0]const u8) ?[*:0]const u8;
    pub const getSysfsAttrUncached = g_udev_device_get_sysfs_attr_uncached;

    /// Gets the sysfs path for `device`.
    extern fn g_udev_device_get_sysfs_path(p_device: *Device) [*:0]const u8;
    pub const getSysfsPath = g_udev_device_get_sysfs_path;

    /// Gets all tags for `device`.
    extern fn g_udev_device_get_tags(p_device: *Device) [*]const [*:0]const u8;
    pub const getTags = g_udev_device_get_tags;

    /// Gets number of micro-seconds since `device` was initialized.
    ///
    /// This only works for devices with properties in the udev
    /// database. All other devices return 0.
    extern fn g_udev_device_get_usec_since_initialized(p_device: *Device) u64;
    pub const getUsecSinceInitialized = g_udev_device_get_usec_since_initialized;

    /// Check if a the property with the given key exists.
    extern fn g_udev_device_has_property(p_device: *Device, p_key: [*:0]const u8) c_int;
    pub const hasProperty = g_udev_device_has_property;

    /// Check if a the sysfs attribute with the given key exists. The
    /// retrieved value is cached in the device. Repeated calls will
    /// return the same result and not check for the presence of the
    /// attribute again, unless updated through one of the "uncached"
    /// functions.
    extern fn g_udev_device_has_sysfs_attr(p_device: *Device, p_key: [*:0]const u8) c_int;
    pub const hasSysfsAttr = g_udev_device_has_sysfs_attr;

    /// Check if a the sysfs attribute with the given key exists. The
    /// retrieved value is cached in the device. Repeated calls will
    /// return the same result and not check for the presence of the
    /// attribute again, unless updated through one of the "uncached"
    /// functions.
    extern fn g_udev_device_has_sysfs_attr_uncached(p_device: *Device, p_key: [*:0]const u8) c_int;
    pub const hasSysfsAttrUncached = g_udev_device_has_sysfs_attr_uncached;

    extern fn g_udev_device_get_type() usize;
    pub const getGObjectType = g_udev_device_get_type;

    extern fn g_object_ref(p_self: *gudev.Device) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gudev.Device) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Device, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gudev.Enumerator` is used to lookup and sort devices.
pub const Enumerator = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gudev.EnumeratorClass;
    f_parent: gobject.Object,
    f_priv: ?*gudev.EnumeratorPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `gudev.Client` to enumerate devices from.
        pub const client = struct {
            pub const name = "client";

            pub const Type = ?*gudev.Client;
        };
    };

    pub const signals = struct {};

    /// Constructs a `gudev.Enumerator` object that can be used to enumerate
    /// and sort devices. Use the add_match_*() and add_nomatch_*() methods
    /// and execute the query to get a list of devices with
    /// `gudev.Enumerator.execute`.
    extern fn g_udev_enumerator_new(p_client: *gudev.Client) *gudev.Enumerator;
    pub const new = g_udev_enumerator_new;

    /// All returned devices will be initialized.
    extern fn g_udev_enumerator_add_match_is_initialized(p_enumerator: *Enumerator) *gudev.Enumerator;
    pub const addMatchIsInitialized = g_udev_enumerator_add_match_is_initialized;

    /// All returned devices will match the given `name`.
    extern fn g_udev_enumerator_add_match_name(p_enumerator: *Enumerator, p_name: [*:0]const u8) *gudev.Enumerator;
    pub const addMatchName = g_udev_enumerator_add_match_name;

    /// All returned devices will have a property matching the given `name` and `value`.
    extern fn g_udev_enumerator_add_match_property(p_enumerator: *Enumerator, p_name: [*:0]const u8, p_value: [*:0]const u8) *gudev.Enumerator;
    pub const addMatchProperty = g_udev_enumerator_add_match_property;

    /// All returned devices will match the given `subsystem`.
    extern fn g_udev_enumerator_add_match_subsystem(p_enumerator: *Enumerator, p_subsystem: [*:0]const u8) *gudev.Enumerator;
    pub const addMatchSubsystem = g_udev_enumerator_add_match_subsystem;

    /// All returned devices will have a sysfs attribute matching the given `name` and `value`.
    extern fn g_udev_enumerator_add_match_sysfs_attr(p_enumerator: *Enumerator, p_name: [*:0]const u8, p_value: [*:0]const u8) *gudev.Enumerator;
    pub const addMatchSysfsAttr = g_udev_enumerator_add_match_sysfs_attr;

    /// All returned devices will match the given `tag`.
    extern fn g_udev_enumerator_add_match_tag(p_enumerator: *Enumerator, p_tag: [*:0]const u8) *gudev.Enumerator;
    pub const addMatchTag = g_udev_enumerator_add_match_tag;

    /// All returned devices will not match the given `subsystem`.
    extern fn g_udev_enumerator_add_nomatch_subsystem(p_enumerator: *Enumerator, p_subsystem: [*:0]const u8) *gudev.Enumerator;
    pub const addNomatchSubsystem = g_udev_enumerator_add_nomatch_subsystem;

    /// All returned devices will not have a sysfs attribute matching the given `name` and `value`.
    extern fn g_udev_enumerator_add_nomatch_sysfs_attr(p_enumerator: *Enumerator, p_name: [*:0]const u8, p_value: [*:0]const u8) *gudev.Enumerator;
    pub const addNomatchSysfsAttr = g_udev_enumerator_add_nomatch_sysfs_attr;

    /// Add a device to the list of devices, to retrieve it back sorted in dependency order.
    extern fn g_udev_enumerator_add_sysfs_path(p_enumerator: *Enumerator, p_sysfs_path: [*:0]const u8) *gudev.Enumerator;
    pub const addSysfsPath = g_udev_enumerator_add_sysfs_path;

    /// Executes the query in `enumerator`.
    extern fn g_udev_enumerator_execute(p_enumerator: *Enumerator) *glib.List;
    pub const execute = g_udev_enumerator_execute;

    extern fn g_udev_enumerator_get_type() usize;
    pub const getGObjectType = g_udev_enumerator_get_type;

    extern fn g_object_ref(p_self: *gudev.Enumerator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gudev.Enumerator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Enumerator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Class structure for `gudev.Client`.
pub const ClientClass = extern struct {
    pub const Instance = gudev.Client;

    /// Parent class.
    f_parent_class: gobject.ObjectClass,
    /// Signal class handler for the `gudev.Client.signals.uevent` signal.
    f_uevent: ?*const fn (p_client: *gudev.Client, p_action: [*:0]const u8, p_device: *gudev.Device) callconv(.c) void,
    f_reserved1: ?*const fn () callconv(.c) void,
    f_reserved2: ?*const fn () callconv(.c) void,
    f_reserved3: ?*const fn () callconv(.c) void,
    f_reserved4: ?*const fn () callconv(.c) void,
    f_reserved5: ?*const fn () callconv(.c) void,
    f_reserved6: ?*const fn () callconv(.c) void,
    f_reserved7: ?*const fn () callconv(.c) void,
    f_reserved8: ?*const fn () callconv(.c) void,

    pub fn as(p_instance: *ClientClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ClientPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Class structure for `gudev.Device`.
pub const DeviceClass = extern struct {
    pub const Instance = gudev.Device;

    /// Parent class.
    f_parent_class: gobject.ObjectClass,
    f_reserved1: ?*const fn () callconv(.c) void,
    f_reserved2: ?*const fn () callconv(.c) void,
    f_reserved3: ?*const fn () callconv(.c) void,
    f_reserved4: ?*const fn () callconv(.c) void,
    f_reserved5: ?*const fn () callconv(.c) void,
    f_reserved6: ?*const fn () callconv(.c) void,
    f_reserved7: ?*const fn () callconv(.c) void,
    f_reserved8: ?*const fn () callconv(.c) void,

    pub fn as(p_instance: *DeviceClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DevicePrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Class structure for `gudev.Enumerator`.
pub const EnumeratorClass = extern struct {
    pub const Instance = gudev.Enumerator;

    /// Parent class.
    f_parent_class: gobject.ObjectClass,
    f_reserved1: ?*const fn () callconv(.c) void,
    f_reserved2: ?*const fn () callconv(.c) void,
    f_reserved3: ?*const fn () callconv(.c) void,
    f_reserved4: ?*const fn () callconv(.c) void,
    f_reserved5: ?*const fn () callconv(.c) void,
    f_reserved6: ?*const fn () callconv(.c) void,
    f_reserved7: ?*const fn () callconv(.c) void,
    f_reserved8: ?*const fn () callconv(.c) void,

    pub fn as(p_instance: *EnumeratorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const EnumeratorPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Enumeration used to specify a the type of a device.
pub const DeviceType = enum(c_int) {
    none = 0,
    block = 98,
    char = 99,
    _,

    extern fn g_udev_device_type_get_type() usize;
    pub const getGObjectType = g_udev_device_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
