cairo/
surface_macros.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// e.g. declare_surface(ImageSurface, SurfaceType::Image)
4macro_rules! declare_surface {
5    ($surf_name:ident, $surf_type:expr) => {
6        #[derive(Debug)]
7        #[repr(transparent)]
8        pub struct $surf_name(Surface);
9
10        impl TryFrom<Surface> for $surf_name {
11            type Error = Surface;
12
13            #[inline]
14            fn try_from(surface: Surface) -> Result<$surf_name, Surface> {
15                if surface.type_() == $surf_type {
16                    Ok($surf_name(surface))
17                } else {
18                    Err(surface)
19                }
20            }
21        }
22
23        impl $surf_name {
24            #[inline]
25            pub unsafe fn from_raw_full(
26                ptr: *mut crate::ffi::cairo_surface_t,
27            ) -> Result<$surf_name, crate::error::Error> {
28                unsafe {
29                    let surface = Surface::from_raw_full(ptr)?;
30                    Self::try_from(surface).map_err(|_| crate::error::Error::SurfaceTypeMismatch)
31                }
32            }
33
34            #[inline]
35            pub unsafe fn from_raw_none(
36                ptr: *mut crate::ffi::cairo_surface_t,
37            ) -> Result<$surf_name, crate::error::Error> {
38                unsafe {
39                    let surface = Surface::from_raw_none(ptr);
40                    Self::try_from(surface).map_err(|_| crate::error::Error::SurfaceTypeMismatch)
41                }
42            }
43        }
44
45        #[cfg(feature = "use_glib")]
46        impl IntoGlibPtr<*mut crate::ffi::cairo_surface_t> for $surf_name {
47            #[inline]
48            fn into_glib_ptr(self) -> *mut crate::ffi::cairo_surface_t {
49                std::mem::ManuallyDrop::new(self).to_glib_none().0
50            }
51        }
52
53        #[cfg(feature = "use_glib")]
54        impl<'a> ToGlibPtr<'a, *mut crate::ffi::cairo_surface_t> for $surf_name {
55            type Storage = std::marker::PhantomData<&'a Surface>;
56
57            #[inline]
58            fn to_glib_none(&'a self) -> Stash<'a, *mut crate::ffi::cairo_surface_t, Self> {
59                let stash = self.0.to_glib_none();
60                Stash(stash.0, stash.1)
61            }
62
63            #[inline]
64            fn to_glib_full(&self) -> *mut crate::ffi::cairo_surface_t {
65                unsafe { crate::ffi::cairo_surface_reference(self.to_glib_none().0) }
66            }
67        }
68
69        #[cfg(feature = "use_glib")]
70        impl FromGlibPtrNone<*mut crate::ffi::cairo_surface_t> for $surf_name {
71            #[inline]
72            unsafe fn from_glib_none(ptr: *mut crate::ffi::cairo_surface_t) -> $surf_name {
73                unsafe { Self::try_from(from_glib_none::<_, Surface>(ptr)).unwrap() }
74            }
75        }
76
77        #[cfg(feature = "use_glib")]
78        impl FromGlibPtrBorrow<*mut crate::ffi::cairo_surface_t> for $surf_name {
79            #[inline]
80            unsafe fn from_glib_borrow(
81                ptr: *mut crate::ffi::cairo_surface_t,
82            ) -> crate::Borrowed<$surf_name> {
83                unsafe {
84                    let surface = from_glib_borrow::<_, Surface>(ptr);
85                    let surface = Self::try_from(surface.into_inner())
86                        .map_err(std::mem::forget)
87                        .unwrap();
88                    crate::Borrowed::new(surface)
89                }
90            }
91        }
92
93        #[cfg(feature = "use_glib")]
94        impl FromGlibPtrFull<*mut crate::ffi::cairo_surface_t> for $surf_name {
95            #[inline]
96            unsafe fn from_glib_full(ptr: *mut crate::ffi::cairo_surface_t) -> $surf_name {
97                unsafe { Self::from_raw_full(ptr).unwrap() }
98            }
99        }
100
101        #[cfg(feature = "use_glib")]
102        gvalue_impl!(
103            $surf_name,
104            crate::ffi::cairo_surface_t,
105            crate::ffi::gobject::cairo_gobject_surface_get_type
106        );
107
108        impl Deref for $surf_name {
109            type Target = Surface;
110
111            #[inline]
112            fn deref(&self) -> &Surface {
113                &self.0
114            }
115        }
116
117        impl AsRef<Surface> for $surf_name {
118            #[inline]
119            fn as_ref(&self) -> &Surface {
120                &self.0
121            }
122        }
123
124        impl Clone for $surf_name {
125            #[inline]
126            fn clone(&self) -> $surf_name {
127                $surf_name(self.0.clone())
128            }
129        }
130    };
131}