Skip to content

Commit f769d0a

Browse files
authored
Merge pull request #1411 from sdroege/value-array-api-improvements
glib: Improve `ValueArray` API, add tests and assertions for invalid …
2 parents 8339a2e + f47f91f commit f769d0a

File tree

1 file changed

+130
-32
lines changed

1 file changed

+130
-32
lines changed

glib/src/value_array.rs

Lines changed: 130 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,28 @@ wrapper! {
1818
}
1919

2020
impl ValueArray {
21-
#[doc(alias = "g_value_array_new")]
22-
pub fn new(n_prealloced: u32) -> ValueArray {
23-
unsafe { from_glib_full(gobject_ffi::g_value_array_new(n_prealloced)) }
21+
#[inline]
22+
pub fn new(values: impl IntoIterator<Item = impl ToValue>) -> Self {
23+
let iter = values.into_iter();
24+
let mut array = Self::with_capacity(iter.size_hint().0);
25+
for v in iter {
26+
array.append(&v.to_value());
27+
}
28+
29+
array
2430
}
2531

26-
#[doc(alias = "g_value_array_append")]
27-
pub fn append(&mut self, value: &Value) {
28-
let value = value.to_glib_none();
29-
unsafe {
30-
gobject_ffi::g_value_array_append(self.to_glib_none_mut().0, value.0);
31-
}
32+
#[inline]
33+
pub fn from_values(values: impl IntoIterator<Item = Value>) -> Self {
34+
Self::new(values)
35+
}
36+
37+
#[doc(alias = "g_value_array_new")]
38+
#[inline]
39+
pub fn with_capacity(capacity: usize) -> ValueArray {
40+
assert!(capacity <= u32::MAX as usize);
41+
42+
unsafe { from_glib_full(gobject_ffi::g_value_array_new(capacity as u32)) }
3243
}
3344

3445
#[inline]
@@ -41,37 +52,61 @@ impl ValueArray {
4152
self.inner.n_values as usize
4253
}
4354

44-
#[doc(alias = "get_nth")]
45-
#[doc(alias = "g_value_array_get_nth")]
46-
pub fn nth(&self, index_: u32) -> Option<Value> {
55+
#[doc(alias = "g_value_array_append")]
56+
#[inline]
57+
pub fn append(&mut self, value: impl ToValue) {
58+
self.append_value(&value.to_value());
59+
}
60+
61+
#[doc(alias = "g_value_array_append")]
62+
#[inline]
63+
pub fn append_value(&mut self, value: &Value) {
4764
unsafe {
48-
from_glib_none(gobject_ffi::g_value_array_get_nth(
49-
mut_override(self.to_glib_none().0),
50-
index_,
51-
))
65+
gobject_ffi::g_value_array_append(self.to_glib_none_mut().0, value.to_glib_none().0);
5266
}
5367
}
5468

5569
#[doc(alias = "g_value_array_insert")]
56-
pub fn insert(&mut self, index_: u32, value: &Value) {
57-
let value = value.to_glib_none();
70+
#[inline]
71+
pub fn insert(&mut self, index_: usize, value: impl ToValue) {
72+
self.insert_value(index_, &value.to_value());
73+
}
74+
75+
#[doc(alias = "g_value_array_insert")]
76+
#[inline]
77+
pub fn insert_value(&mut self, index_: usize, value: &Value) {
78+
assert!(index_ <= self.len());
79+
5880
unsafe {
59-
gobject_ffi::g_value_array_insert(self.to_glib_none_mut().0, index_, value.0);
81+
gobject_ffi::g_value_array_insert(
82+
self.to_glib_none_mut().0,
83+
index_ as u32,
84+
value.to_glib_none().0,
85+
);
6086
}
6187
}
6288

6389
#[doc(alias = "g_value_array_prepend")]
64-
pub fn prepend(&mut self, value: &Value) {
65-
let value = value.to_glib_none();
90+
#[inline]
91+
pub fn prepend(&mut self, value: impl ToValue) {
92+
self.prepend_value(&value.to_value());
93+
}
94+
95+
#[doc(alias = "g_value_array_prepend")]
96+
#[inline]
97+
pub fn prepend_value(&mut self, value: &Value) {
6698
unsafe {
67-
gobject_ffi::g_value_array_prepend(self.to_glib_none_mut().0, value.0);
99+
gobject_ffi::g_value_array_prepend(self.to_glib_none_mut().0, value.to_glib_none().0);
68100
}
69101
}
70102

71103
#[doc(alias = "g_value_array_remove")]
72-
pub fn remove(&mut self, index_: u32) {
104+
#[inline]
105+
pub fn remove(&mut self, index_: usize) {
106+
assert!(index_ < self.len());
107+
73108
unsafe {
74-
gobject_ffi::g_value_array_remove(self.to_glib_none_mut().0, index_);
109+
gobject_ffi::g_value_array_remove(self.to_glib_none_mut().0, index_ as u32);
75110
}
76111
}
77112

@@ -102,13 +137,9 @@ impl ValueArray {
102137
);
103138
}
104139
}
105-
}
106-
107-
impl ops::Deref for ValueArray {
108-
type Target = [Value];
109140

110141
#[inline]
111-
fn deref(&self) -> &[Value] {
142+
pub fn as_slice(&self) -> &[Value] {
112143
if self.is_empty() {
113144
return &[];
114145
}
@@ -120,11 +151,9 @@ impl ops::Deref for ValueArray {
120151
)
121152
}
122153
}
123-
}
124154

125-
impl ops::DerefMut for ValueArray {
126155
#[inline]
127-
fn deref_mut(&mut self) -> &mut [Value] {
156+
pub fn as_mut_slice(&mut self) -> &mut [Value] {
128157
if self.is_empty() {
129158
return &mut [];
130159
}
@@ -138,6 +167,42 @@ impl ops::DerefMut for ValueArray {
138167
}
139168
}
140169

170+
impl ops::Deref for ValueArray {
171+
type Target = [Value];
172+
173+
#[inline]
174+
fn deref(&self) -> &[Value] {
175+
self.as_slice()
176+
}
177+
}
178+
179+
impl ops::DerefMut for ValueArray {
180+
#[inline]
181+
fn deref_mut(&mut self) -> &mut [Value] {
182+
self.as_mut_slice()
183+
}
184+
}
185+
186+
impl Default for ValueArray {
187+
fn default() -> Self {
188+
Self::with_capacity(8)
189+
}
190+
}
191+
192+
impl std::iter::FromIterator<Value> for ValueArray {
193+
fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
194+
Self::from_values(iter)
195+
}
196+
}
197+
198+
impl std::iter::Extend<Value> for ValueArray {
199+
fn extend<T: IntoIterator<Item = Value>>(&mut self, iter: T) {
200+
for v in iter.into_iter() {
201+
self.append_value(&v);
202+
}
203+
}
204+
}
205+
141206
// Implementing `Value` traits manually because of a custom ParamSpec
142207
impl StaticType for ValueArray {
143208
#[inline]
@@ -244,3 +309,36 @@ impl HasParamSpec for ValueArray {
244309
Self::ParamSpec::builder
245310
}
246311
}
312+
313+
#[cfg(test)]
314+
mod tests {
315+
use super::*;
316+
317+
#[test]
318+
fn test_new() {
319+
let arr = ValueArray::new(["123", "456"]);
320+
assert_eq!(
321+
arr.first().and_then(|v| v.get::<String>().ok()),
322+
Some(String::from("123"))
323+
);
324+
assert_eq!(
325+
arr.get(1).and_then(|v| v.get::<String>().ok()),
326+
Some(String::from("456"))
327+
);
328+
}
329+
330+
#[test]
331+
fn test_append() {
332+
let mut arr = ValueArray::default();
333+
arr.append("123");
334+
arr.append(123u32);
335+
arr.append_value(&Value::from(456u64));
336+
337+
assert_eq!(
338+
arr.first().and_then(|v| v.get::<String>().ok()),
339+
Some(String::from("123"))
340+
);
341+
assert_eq!(arr.get(1).and_then(|v| v.get::<u32>().ok()), Some(123));
342+
assert_eq!(arr.get(2).and_then(|v| v.get::<u64>().ok()), Some(456));
343+
}
344+
}

0 commit comments

Comments
 (0)