1use std::marker::PhantomData;
4
5use glib::translate::*;
6
7use crate::{ffi, Bitset};
8
9#[derive(Copy, Clone)]
10#[doc(alias = "GtkBitsetIter")]
11#[repr(transparent)]
12pub struct BitsetIter<'a>(ffi::GtkBitsetIter, PhantomData<&'a Bitset>);
13
14impl<'a> BitsetIter<'a> {
15 #[doc(alias = "gtk_bitset_iter_init_at")]
16 pub fn init_at(set: &'a Bitset, target: u32) -> Option<(Self, u32)> {
17 assert_initialized_main_thread!();
18 unsafe {
19 let mut iter = std::mem::MaybeUninit::uninit();
20 let mut value = std::mem::MaybeUninit::uninit();
21 let found: bool = from_glib(ffi::gtk_bitset_iter_init_at(
22 iter.as_mut_ptr(),
23 set.to_glib_none().0,
24 target,
25 value.as_mut_ptr(),
26 ));
27
28 if found {
29 Some((
30 BitsetIter(iter.assume_init(), PhantomData),
31 value.assume_init(),
32 ))
33 } else {
34 None
35 }
36 }
37 }
38
39 #[doc(alias = "gtk_bitset_iter_init_first")]
40 pub fn init_first(set: &'a Bitset) -> Option<(Self, u32)> {
41 assert_initialized_main_thread!();
42 unsafe {
43 let mut iter = std::mem::MaybeUninit::uninit();
44 let mut value = std::mem::MaybeUninit::uninit();
45 let found: bool = from_glib(ffi::gtk_bitset_iter_init_first(
46 iter.as_mut_ptr(),
47 set.to_glib_none().0,
48 value.as_mut_ptr(),
49 ));
50 if found {
51 Some((
52 BitsetIter(iter.assume_init(), PhantomData),
53 value.assume_init(),
54 ))
55 } else {
56 None
57 }
58 }
59 }
60
61 #[doc(alias = "gtk_bitset_iter_init_last")]
62 pub fn init_last(set: &'a Bitset) -> Option<(Self, u32)> {
63 assert_initialized_main_thread!();
64 unsafe {
65 let mut iter = std::mem::MaybeUninit::uninit();
66 let mut value = std::mem::MaybeUninit::uninit();
67 let found: bool = from_glib(ffi::gtk_bitset_iter_init_last(
68 iter.as_mut_ptr(),
69 set.to_glib_none().0,
70 value.as_mut_ptr(),
71 ));
72 if found {
73 Some((
74 BitsetIter(iter.assume_init(), PhantomData),
75 value.assume_init(),
76 ))
77 } else {
78 None
79 }
80 }
81 }
82
83 #[doc(alias = "gtk_bitset_iter_get_value")]
84 pub fn value(&self) -> u32 {
85 unsafe { ffi::gtk_bitset_iter_get_value(self.to_glib_none().0) }
86 }
87
88 #[doc(alias = "gtk_bitset_iter_is_valid")]
89 pub fn is_valid(&self) -> bool {
90 unsafe { from_glib(ffi::gtk_bitset_iter_is_valid(self.to_glib_none().0)) }
91 }
92
93 #[doc(alias = "gtk_bitset_iter_previous")]
94 pub fn previous(&mut self) -> Option<u32> {
95 unsafe {
96 let mut value = std::mem::MaybeUninit::uninit();
97
98 let found: bool = from_glib(ffi::gtk_bitset_iter_previous(
99 &mut self.0 as *mut _,
100 value.as_mut_ptr(),
101 ));
102 if found {
103 Some(value.assume_init())
104 } else {
105 None
106 }
107 }
108 }
109}
110
111impl Iterator for BitsetIter<'_> {
112 type Item = u32;
113
114 #[doc(alias = "gtk_bitset_iter_next")]
115 fn next(&mut self) -> Option<Self::Item> {
116 unsafe {
117 let mut value = std::mem::MaybeUninit::uninit();
118
119 let found: bool = from_glib(ffi::gtk_bitset_iter_next(
120 &mut self.0 as *mut _,
121 value.as_mut_ptr(),
122 ));
123 if found {
124 Some(value.assume_init())
125 } else {
126 None
127 }
128 }
129 }
130}
131
132impl std::iter::FusedIterator for BitsetIter<'_> {}
133
134#[doc(hidden)]
135impl<'a> ToGlibPtr<'a, *const ffi::GtkBitsetIter> for BitsetIter<'a> {
136 type Storage = &'a Self;
137
138 #[inline]
139 fn to_glib_none(&'a self) -> Stash<'a, *const ffi::GtkBitsetIter, Self> {
140 Stash(&self.0 as *const ffi::GtkBitsetIter, self)
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use crate as gtk4;
148
149 #[test]
150 fn test_bitset_iter() {
151 let set = Bitset::new_range(0, 20);
152 let (mut iter, init_value) = BitsetIter::init_first(&set).unwrap();
153 assert_eq!(init_value, 0);
154 assert_eq!(iter.next(), Some(1));
155 assert_eq!(iter.previous(), Some(0));
156
157 let set2 = Bitset::new_range(0, 3);
158 let (mut iter, init_val) = BitsetIter::init_last(&set2).unwrap();
159 assert_eq!(init_val, 2);
160 assert_eq!(iter.previous(), Some(1));
161 assert_eq!(iter.previous(), Some(0));
162 assert_eq!(iter.previous(), None);
163 assert!(!iter.is_valid());
164 }
165}