glib_signal/
borrowed_object.rs

1use {
2	glib::{
3		object::ObjectType,
4		translate::{from_glib_borrow, FromGlibPtrBorrow, ToGlibPtr},
5		types::StaticType,
6		value::FromValue,
7		Type, Value,
8	},
9	std::{marker::PhantomData, mem::ManuallyDrop, ops::Deref},
10};
11
12#[derive(Debug)]
13#[repr(transparent)]
14pub struct BorrowedObject<'a, O> {
15	inner: ManuallyDrop<O>,
16	_borrow: PhantomData<&'a O>,
17}
18
19impl<'a, O> BorrowedObject<'a, O> {
20	pub fn forget(inner: O) -> Self {
21		Self {
22			inner: ManuallyDrop::new(inner),
23			_borrow: PhantomData,
24		}
25	}
26
27	/// If `O` lives beyond `'a`, bad things may happen.
28	pub unsafe fn into_inner(self) -> ManuallyDrop<O> {
29		self.inner
30	}
31}
32
33impl<'a, O: ObjectType> BorrowedObject<'a, O> {
34	/// Copy this reference
35	pub fn copy_ref(&self) -> Self {
36		unsafe { std::ptr::read(self) }
37	}
38}
39
40impl<'a, O> Deref for BorrowedObject<'a, O> {
41	type Target = O;
42
43	fn deref(&self) -> &Self::Target {
44		&self.inner
45	}
46}
47
48impl<'a, O> AsRef<O> for BorrowedObject<'a, O> {
49	fn as_ref(&self) -> &O {
50		&self.inner
51	}
52}
53
54unsafe impl<'a, O: ObjectType + FromGlibPtrBorrow<*mut O::GlibType>> FromValue<'a> for BorrowedObject<'a, O> {
55	type Checker = glib::value::GenericValueTypeChecker<O>;
56
57	unsafe fn from_value(value: &'a Value) -> Self {
58		let value = value.to_glib_none();
59		let borrowed: glib::translate::Borrowed<O> =
60			from_glib_borrow(glib::gobject_ffi::g_value_get_object(value.0) as *mut O::GlibType);
61		Self::forget(borrowed.into_inner())
62	}
63}
64
65impl<'a, O: StaticType> StaticType for BorrowedObject<'a, O> {
66	fn static_type() -> Type {
67		O::static_type()
68	}
69}