1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
// Take a look at the license at the top of the repository in the LICENSE file.
use std::marker::PhantomData;
use glib::{object::IsClass, prelude::*, Object, Type};
use crate::{prelude::*, Cancellable, Initable};
impl Initable {
// rustdoc-stripper-ignore-next
/// Create a new instance of an object with the default property values.
///
/// Similar to [`Object::new`] but can fail because the object initialization in
/// `Initable::init` failed.
// rustdoc-stripper-ignore-next-stop
/// Helper function for constructing [`Initable`][crate::Initable] object. This is
/// similar to [`glib::Object::new()`][crate::glib::Object::new()] but also initializes the object
/// and returns [`None`], setting an error on failure.
/// ## `object_type`
/// a `GType` supporting [`Initable`][crate::Initable].
/// ## `cancellable`
/// optional [`Cancellable`][crate::Cancellable] object, [`None`] to ignore.
/// ## `first_property_name`
/// the name of the first property, or [`None`] if no
/// properties
///
/// # Returns
///
/// a newly allocated
/// [`glib::Object`][crate::glib::Object], or [`None`] on error
#[track_caller]
#[allow(clippy::new_ret_no_self)]
pub fn new<T: IsA<Object> + IsClass + IsA<Initable>>(
cancellable: Option<&impl IsA<Cancellable>>,
) -> Result<T, glib::Error> {
let object = Self::with_type(T::static_type(), cancellable)?;
Ok(unsafe { object.unsafe_cast() })
}
// rustdoc-stripper-ignore-next
/// Create a new instance of an object with the default property values.
///
/// Similar to [`Object::with_type`] but can fail because the object initialization in
/// `Initable::init` failed.
#[track_caller]
pub fn with_type(
type_: Type,
cancellable: Option<&impl IsA<Cancellable>>,
) -> Result<Object, glib::Error> {
if !type_.is_a(Initable::static_type()) {
panic!("Type '{type_}' is not initable");
}
unsafe {
let object = Object::new_internal(type_, &mut []);
object.unsafe_cast_ref::<Self>().init(cancellable)?;
Ok(object)
}
}
// rustdoc-stripper-ignore-next
/// Create a new instance of an object of the given type with the given properties as mutable
/// values.
///
/// # Panics
///
/// This panics if the object is not instantiable, doesn't have all the given properties or
/// property values of the wrong type are provided.
#[track_caller]
pub fn with_mut_values(
type_: Type,
properties: &mut [(&str, glib::Value)],
cancellable: Option<&impl IsA<Cancellable>>,
) -> Result<Object, glib::Error> {
if !type_.is_a(Initable::static_type()) {
panic!("Type '{type_}' is not initable");
}
unsafe {
let object = Object::new_internal(type_, properties);
object.unsafe_cast_ref::<Self>().init(cancellable)?;
Ok(object)
}
}
// rustdoc-stripper-ignore-next
/// Create a new object builder for a specific type.
pub fn builder<'a, O: IsA<Object> + IsClass + IsA<Initable>>() -> InitableBuilder<'a, O> {
InitableBuilder::new(O::static_type())
}
// rustdoc-stripper-ignore-next
/// Create a new object builder for a specific type.
pub fn builder_with_type<'a>(type_: Type) -> InitableBuilder<'a, Object> {
if !type_.is_a(Initable::static_type()) {
panic!("Type '{type_}' is not initable");
}
InitableBuilder::new(type_)
}
}
#[must_use = "builder doesn't do anything unless built"]
pub struct InitableBuilder<'a, O> {
type_: Type,
properties: smallvec::SmallVec<[(&'a str, glib::Value); 16]>,
phantom: PhantomData<O>,
}
impl<'a, O: IsA<Object> + IsClass> InitableBuilder<'a, O> {
#[inline]
fn new(type_: Type) -> Self {
InitableBuilder {
type_,
properties: smallvec::SmallVec::new(),
phantom: PhantomData,
}
}
// rustdoc-stripper-ignore-next
/// Gets the type of this builder.
#[inline]
pub fn type_(&self) -> Type {
self.type_
}
// rustdoc-stripper-ignore-next
/// Set property `name` to the given value `value`.
#[inline]
pub fn property(self, name: &'a str, value: impl Into<glib::Value>) -> Self {
let InitableBuilder {
type_,
mut properties,
..
} = self;
properties.push((name, value.into()));
InitableBuilder {
type_,
properties,
phantom: PhantomData,
}
}
// rustdoc-stripper-ignore-next
/// Build the object with the provided properties.
///
/// # Panics
///
/// This panics if the object is not instantiable, doesn't have all the given properties or
/// property values of the wrong type are provided.
#[track_caller]
#[inline]
pub fn build(mut self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<O, glib::Error> {
let object = Initable::with_mut_values(self.type_, &mut self.properties, cancellable)?;
Ok(unsafe { object.unsafe_cast::<O>() })
}
}