1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::{cmp::Ordering, ops, slice}; |
4 | |
5 | use crate::{ |
6 | prelude::*, |
7 | translate::*, |
8 | value::{ |
9 | FromValue, GenericValueTypeOrNoneChecker, ToValueOptional, ValueType, ValueTypeOptional, |
10 | }, |
11 | HasParamSpec, ParamSpecValueArray, ParamSpecValueArrayBuilder, Type, Value, |
12 | }; |
13 | |
14 | wrapper! { |
15 | #[derive (Debug)] |
16 | #[doc (alias = "GValueArray" )] |
17 | pub struct ValueArray(Boxed<gobject_ffi::GValueArray>); |
18 | |
19 | match fn { |
20 | copy => |ptr| gobject_ffi::g_value_array_copy(mut_override(ptr)), |
21 | free => |ptr| gobject_ffi::g_value_array_free(ptr), |
22 | } |
23 | } |
24 | |
25 | impl ValueArray { |
26 | #[doc (alias = "g_value_array_new" )] |
27 | pub fn new(n_prealloced: u32) -> ValueArray { |
28 | unsafe { from_glib_full(gobject_ffi::g_value_array_new(n_prealloced)) } |
29 | } |
30 | |
31 | #[doc (alias = "g_value_array_append" )] |
32 | pub fn append(&mut self, value: &Value) { |
33 | let value = value.to_glib_none(); |
34 | unsafe { |
35 | gobject_ffi::g_value_array_append(self.to_glib_none_mut().0, value.0); |
36 | } |
37 | } |
38 | |
39 | #[inline ] |
40 | pub fn is_empty(&self) -> bool { |
41 | self.len() == 0 |
42 | } |
43 | |
44 | #[inline ] |
45 | pub fn len(&self) -> usize { |
46 | self.inner.n_values as usize |
47 | } |
48 | |
49 | #[doc (alias = "get_nth" )] |
50 | #[doc (alias = "g_value_array_get_nth" )] |
51 | pub fn nth(&self, index_: u32) -> Option<Value> { |
52 | unsafe { |
53 | from_glib_none(gobject_ffi::g_value_array_get_nth( |
54 | mut_override(self.to_glib_none().0), |
55 | index_, |
56 | )) |
57 | } |
58 | } |
59 | |
60 | #[doc (alias = "g_value_array_insert" )] |
61 | pub fn insert(&mut self, index_: u32, value: &Value) { |
62 | let value = value.to_glib_none(); |
63 | unsafe { |
64 | gobject_ffi::g_value_array_insert(self.to_glib_none_mut().0, index_, value.0); |
65 | } |
66 | } |
67 | |
68 | #[doc (alias = "g_value_array_prepend" )] |
69 | pub fn prepend(&mut self, value: &Value) { |
70 | let value = value.to_glib_none(); |
71 | unsafe { |
72 | gobject_ffi::g_value_array_prepend(self.to_glib_none_mut().0, value.0); |
73 | } |
74 | } |
75 | |
76 | #[doc (alias = "g_value_array_remove" )] |
77 | pub fn remove(&mut self, index_: u32) { |
78 | unsafe { |
79 | gobject_ffi::g_value_array_remove(self.to_glib_none_mut().0, index_); |
80 | } |
81 | } |
82 | |
83 | #[doc (alias = "g_value_array_sort_with_data" )] |
84 | pub fn sort_with_data<F: FnMut(&Value, &Value) -> Ordering>(&mut self, compare_func: F) { |
85 | unsafe extern "C" fn compare_func_trampoline( |
86 | a: ffi::gconstpointer, |
87 | b: ffi::gconstpointer, |
88 | func: ffi::gpointer, |
89 | ) -> i32 { |
90 | let func = func as *mut &mut (dyn FnMut(&Value, &Value) -> Ordering); |
91 | |
92 | let a = &*(a as *const Value); |
93 | let b = &*(b as *const Value); |
94 | |
95 | (*func)(a, b).into_glib() |
96 | } |
97 | unsafe { |
98 | let mut func = compare_func; |
99 | let func_obj: &mut (dyn FnMut(&Value, &Value) -> Ordering) = &mut func; |
100 | let func_ptr = |
101 | &func_obj as *const &mut (dyn FnMut(&Value, &Value) -> Ordering) as ffi::gpointer; |
102 | |
103 | gobject_ffi::g_value_array_sort_with_data( |
104 | self.to_glib_none_mut().0, |
105 | Some(compare_func_trampoline), |
106 | func_ptr, |
107 | ); |
108 | } |
109 | } |
110 | } |
111 | |
112 | impl ops::Deref for ValueArray { |
113 | type Target = [Value]; |
114 | |
115 | #[inline ] |
116 | fn deref(&self) -> &[Value] { |
117 | if self.is_empty() { |
118 | return &[]; |
119 | } |
120 | |
121 | unsafe { |
122 | slice::from_raw_parts( |
123 | (*self.as_ptr()).values as *const Value, |
124 | (*self.as_ptr()).n_values as usize, |
125 | ) |
126 | } |
127 | } |
128 | } |
129 | |
130 | impl ops::DerefMut for ValueArray { |
131 | #[inline ] |
132 | fn deref_mut(&mut self) -> &mut [Value] { |
133 | if self.is_empty() { |
134 | return &mut []; |
135 | } |
136 | |
137 | unsafe { |
138 | slice::from_raw_parts_mut( |
139 | (*self.as_ptr()).values as *mut Value, |
140 | (*self.as_ptr()).n_values as usize, |
141 | ) |
142 | } |
143 | } |
144 | } |
145 | |
146 | // Implementing `Value` traits manually because of a custom ParamSpec |
147 | impl StaticType for ValueArray { |
148 | #[inline ] |
149 | fn static_type() -> Type { |
150 | unsafe { from_glib(val:gobject_ffi::g_value_array_get_type()) } |
151 | } |
152 | } |
153 | |
154 | #[doc (hidden)] |
155 | impl ValueType for ValueArray { |
156 | type Type = Self; |
157 | } |
158 | |
159 | #[doc (hidden)] |
160 | impl ValueTypeOptional for ValueArray {} |
161 | |
162 | #[doc (hidden)] |
163 | unsafe impl<'a> FromValue<'a> for ValueArray { |
164 | type Checker = GenericValueTypeOrNoneChecker<Self>; |
165 | |
166 | #[inline ] |
167 | unsafe fn from_value(value: &'a Value) -> Self { |
168 | let ptr: *mut c_void = gobject_ffi::g_value_dup_boxed(value.to_glib_none().0); |
169 | debug_assert!(!ptr.is_null()); |
170 | from_glib_full(ptr as *mut gobject_ffi::GValueArray) |
171 | } |
172 | } |
173 | |
174 | #[doc (hidden)] |
175 | unsafe impl<'a> FromValue<'a> for &'a ValueArray { |
176 | type Checker = GenericValueTypeOrNoneChecker<Self>; |
177 | |
178 | #[inline ] |
179 | unsafe fn from_value(value: &'a Value) -> Self { |
180 | debug_assert_eq!( |
181 | std::mem::size_of::<Self>(), |
182 | std::mem::size_of::<ffi::gpointer>() |
183 | ); |
184 | let value: &GValue = &*(value as *const Value as *const gobject_ffi::GValue); |
185 | debug_assert!(!value.data[0].v_pointer.is_null()); |
186 | <ValueArray>::from_glib_ptr_borrow( |
187 | &value.data[0].v_pointer as *const ffi::gpointer |
188 | as *const *const gobject_ffi::GValueArray, |
189 | ) |
190 | } |
191 | } |
192 | |
193 | #[doc (hidden)] |
194 | impl ToValue for ValueArray { |
195 | #[inline ] |
196 | fn to_value(&self) -> Value { |
197 | unsafe { |
198 | let mut value: Value = Value::from_type_unchecked(<Self as StaticType>::static_type()); |
199 | gobject_ffi::g_value_take_boxed( |
200 | value:value.to_glib_none_mut().0, |
201 | v_boxed:ToGlibPtr::<*mut gobject_ffi::GValueArray>::to_glib_full(self) as *mut _, |
202 | ); |
203 | value |
204 | } |
205 | } |
206 | |
207 | #[inline ] |
208 | fn value_type(&self) -> Type { |
209 | <Self as StaticType>::static_type() |
210 | } |
211 | } |
212 | |
213 | impl std::convert::From<ValueArray> for Value { |
214 | #[inline ] |
215 | fn from(o: ValueArray) -> Self { |
216 | unsafe { |
217 | let mut value: Value = Value::from_type_unchecked(<ValueArray as StaticType>::static_type()); |
218 | gobject_ffi::g_value_take_boxed( |
219 | value:value.to_glib_none_mut().0, |
220 | v_boxed:IntoGlibPtr::<*mut gobject_ffi::GValueArray>::into_glib_ptr(self:o) as *mut _, |
221 | ); |
222 | value |
223 | } |
224 | } |
225 | } |
226 | |
227 | #[doc (hidden)] |
228 | impl ToValueOptional for ValueArray { |
229 | #[inline ] |
230 | fn to_value_optional(s: Option<&Self>) -> Value { |
231 | let mut value: Value = Value::for_value_type::<Self>(); |
232 | unsafe { |
233 | gobject_ffi::g_value_take_boxed( |
234 | value:value.to_glib_none_mut().0, |
235 | v_boxed:ToGlibPtr::<*mut gobject_ffi::GValueArray>::to_glib_full(&s) as *mut _, |
236 | ); |
237 | } |
238 | |
239 | value |
240 | } |
241 | } |
242 | |
243 | impl HasParamSpec for ValueArray { |
244 | type ParamSpec = ParamSpecValueArray; |
245 | type SetValue = Self; |
246 | type BuilderFn = fn(&str) -> ParamSpecValueArrayBuilder; |
247 | |
248 | fn param_spec_builder() -> Self::BuilderFn { |
249 | Self::ParamSpec::builder |
250 | } |
251 | } |
252 | |