1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{cmp::Ordering, ops, slice};
4
5use crate::{
6 prelude::*,
7 translate::*,
8 value::{
9 FromValue, GenericValueTypeOrNoneChecker, ToValueOptional, ValueType, ValueTypeOptional,
10 },
11 HasParamSpec, ParamSpecValueArray, ParamSpecValueArrayBuilder, Type, Value,
12};
13
14wrapper! {
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
25impl 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
112impl 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
130impl 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
147impl 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)]
155impl ValueType for ValueArray {
156 type Type = Self;
157}
158
159#[doc(hidden)]
160impl ValueTypeOptional for ValueArray {}
161
162#[doc(hidden)]
163unsafe 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)]
175unsafe 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)]
194impl 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
213impl 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)]
228impl 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
243impl 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