pango/
attribute.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{ffi, AttrClass, AttrType, Attribute};
6
7impl Attribute {
8    #[doc(alias = "get_attr_class")]
9    #[inline]
10    pub fn attr_class(&self) -> AttrClass {
11        unsafe { from_glib_none((*self.as_ptr()).klass) }
12    }
13
14    #[inline]
15    pub fn type_(&self) -> AttrType {
16        unsafe { from_glib((*(*self.as_ptr()).klass).type_) }
17    }
18
19    #[doc(alias = "get_start_index")]
20    #[inline]
21    pub fn start_index(&self) -> u32 {
22        unsafe { (*self.as_ptr()).start_index }
23    }
24
25    #[doc(alias = "get_end_index")]
26    #[inline]
27    pub fn end_index(&self) -> u32 {
28        unsafe { (*self.as_ptr()).end_index }
29    }
30
31    #[inline]
32    pub fn set_start_index(&mut self, index: u32) {
33        unsafe {
34            (*self.as_ptr()).start_index = index;
35        }
36    }
37
38    #[inline]
39    pub fn set_end_index(&mut self, index: u32) {
40        unsafe {
41            (*self.as_ptr()).end_index = index;
42        }
43    }
44
45    #[inline]
46    pub fn downcast<T: IsAttribute>(self) -> Result<T, Attribute> {
47        unsafe {
48            if T::ATTR_TYPES.contains(&self.attr_class().type_()) {
49                Ok(from_glib_full(glib::translate::IntoGlibPtr::<
50                    *mut ffi::PangoAttribute,
51                >::into_glib_ptr(self)))
52            } else {
53                Err(self)
54            }
55        }
56    }
57
58    #[inline]
59    pub fn downcast_ref<T: IsAttribute>(&self) -> Option<&T> {
60        unsafe {
61            if T::ATTR_TYPES.contains(&self.attr_class().type_()) {
62                Some(&*(self as *const Attribute as *const T))
63            } else {
64                None
65            }
66        }
67    }
68}
69
70#[allow(clippy::missing_safety_doc)]
71pub unsafe trait IsAttribute:
72    FromGlibPtrFull<*const ffi::PangoAttribute>
73    + FromGlibPtrFull<*mut ffi::PangoAttribute>
74    + std::convert::AsRef<crate::Attribute>
75    + 'static
76{
77    const ATTR_TYPES: &'static [AttrType];
78    fn upcast(self) -> Attribute;
79    fn upcast_ref(&self) -> &Attribute;
80}
81
82macro_rules! define_attribute_struct {
83    ($rust_type:ident, $ffi_type:path, $attr_types:expr) => {
84
85        #[cfg(feature = "v1_44")]
86        glib::wrapper! {
87            #[derive(Debug)]
88            pub struct $rust_type(Boxed<$ffi_type>);
89
90            match fn {
91                copy => |ptr| ffi::pango_attribute_copy(ptr as *const ffi::PangoAttribute) as *mut $ffi_type,
92                free => |ptr| ffi::pango_attribute_destroy(ptr as *mut ffi::PangoAttribute),
93                type_ => || ffi::pango_attribute_get_type(),
94            }
95        }
96
97        unsafe impl Send for $rust_type {}
98        unsafe impl Sync for $rust_type {}
99
100        #[cfg(not(feature = "v1_44"))]
101        glib::wrapper! {
102            #[derive(Debug)]
103            pub struct $rust_type(Boxed<$ffi_type>);
104
105            match fn {
106                copy => |ptr| ffi::pango_attribute_copy(ptr as *const ffi::PangoAttribute) as *mut $ffi_type,
107                free => |ptr| ffi::pango_attribute_destroy(ptr as *mut ffi::PangoAttribute),
108            }
109        }
110
111        impl $rust_type {
112            #[doc(alias = "pango_attribute_equal")]
113            fn equal<T:  crate::attribute::IsAttribute>(&self, attr2: &T) -> bool {
114                unsafe {
115                    glib::translate::from_glib(ffi::pango_attribute_equal(self.as_ptr() as *const ffi::PangoAttribute,
116                       glib::translate::ToGlibPtr::to_glib_none(attr2.upcast_ref()).0,
117                    ))
118                }
119            }
120        }
121
122        impl PartialEq for $rust_type {
123            #[inline]
124            fn eq(&self, other: &Self) -> bool {
125                self.equal(other)
126            }
127        }
128
129        impl Eq for $rust_type {}
130
131        unsafe impl crate::attribute::IsAttribute for $rust_type {
132            const ATTR_TYPES: &'static [crate::AttrType] = $attr_types;
133
134            #[inline]
135            fn upcast(self) -> crate::Attribute {
136                unsafe { glib::translate::from_glib_full(glib::translate::IntoGlibPtr::<*mut $ffi_type>::into_glib_ptr(self) as *mut ffi::PangoAttribute) }
137            }
138
139            #[inline]
140            fn upcast_ref(&self) -> &crate::Attribute {
141                &*self
142            }
143        }
144
145        #[doc(hidden)]
146        impl glib::translate::FromGlibPtrFull<*mut ffi::PangoAttribute> for $rust_type {
147            #[inline]
148            unsafe fn from_glib_full(ptr: *mut ffi::PangoAttribute) -> Self {
149                glib::translate::from_glib_full(ptr as *mut $ffi_type)
150            }
151        }
152
153        #[doc(hidden)]
154        impl glib::translate::FromGlibPtrFull<*const ffi::PangoAttribute> for $rust_type {
155            #[inline]
156            unsafe fn from_glib_full(ptr: *const ffi::PangoAttribute) -> Self {
157                glib::translate::from_glib_full(ptr as *const $ffi_type)
158            }
159        }
160
161        impl std::convert::AsRef<crate::Attribute> for $rust_type {
162            #[inline]
163            fn as_ref(&self) -> &crate::Attribute {
164                &*self
165            }
166        }
167
168        impl From<$rust_type> for crate::Attribute {
169            #[inline]
170            fn from(attr: $rust_type) -> crate::Attribute {
171                crate::IsAttribute::upcast(attr)
172            }
173        }
174
175        impl std::ops::Deref for $rust_type {
176            type Target = crate::Attribute;
177
178            #[inline]
179            fn deref(&self) -> &Self::Target {
180                unsafe { &*(self as *const $rust_type as *const crate::Attribute) }
181            }
182        }
183
184        impl std::ops::DerefMut for $rust_type {
185            #[inline]
186            fn deref_mut(&mut self) -> &mut crate::Attribute {
187                unsafe { &mut *(self as *mut $rust_type as *mut crate::Attribute) }
188            }
189        }
190    }
191}