1use std::alloc::Layout;
2use std::ptr::null_mut;
3
4use crate::object::{AsRawMutObject, Keyed, WafArray, WafMap, WafObject};
5
6impl IntoIterator for WafArray {
7 type Item = WafObject;
8 type IntoIter = WafIter<Self::Item>;
9
10 fn into_iter(self) -> Self::IntoIter {
11 let array: *mut Self::Item = unsafe { self.raw.__bindgen_anon_1.array.cast() };
12 let len = if array.is_null() { 0 } else { self.len() };
13 std::mem::forget(self);
15 WafIter { array, len, pos: 0 }
16 }
17}
18
19impl IntoIterator for Keyed<WafArray> {
20 type Item = WafObject;
21 type IntoIter = WafIter<Self::Item>;
22
23 fn into_iter(mut self) -> Self::IntoIter {
24 let mut arr = std::mem::take(&mut self.value);
25
26 let raw_obj = unsafe { AsRawMutObject::as_raw_mut(&mut arr) };
29 unsafe { raw_obj.drop_key() };
30 raw_obj.parameterName = null_mut();
31 raw_obj.parameterNameLength = 0;
32
33 arr.into_iter()
35 }
36}
37
38impl IntoIterator for WafMap {
39 type Item = Keyed<WafObject>;
40 type IntoIter = WafIter<Self::Item>;
41
42 fn into_iter(self) -> Self::IntoIter {
43 let array: *mut Keyed<WafObject> = unsafe { self.raw.__bindgen_anon_1.array.cast() };
44 let len = if array.is_null() { 0 } else { self.len() };
45 std::mem::forget(self);
47 WafIter { array, len, pos: 0 }
48 }
49}
50
51impl IntoIterator for Keyed<WafMap> {
52 type Item = Keyed<WafObject>;
53 type IntoIter = WafIter<Self::Item>;
54
55 fn into_iter(mut self) -> Self::IntoIter {
56 let mut arr = std::mem::take(&mut self.value);
57
58 let raw_obj = unsafe { AsRawMutObject::as_raw_mut(&mut arr) };
61 unsafe { raw_obj.drop_key() };
62 raw_obj.parameterName = null_mut();
63 raw_obj.parameterNameLength = 0;
64
65 arr.into_iter()
67 }
68}
69
70pub struct WafIter<T> {
72 array: *mut T,
73 len: usize,
74 pos: usize,
75}
76impl<T: Default> Iterator for WafIter<T> {
77 type Item = T;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 if self.pos >= self.len {
81 return None;
82 }
83
84 let obj = unsafe { &mut *self.array.add(self.pos) };
85 self.pos += 1;
86 Some(std::mem::take(obj))
87 }
88}
89impl<T> Drop for WafIter<T> {
90 fn drop(&mut self) {
91 for i in self.pos..self.len {
93 let elem = unsafe { self.array.add(i) };
94 unsafe { elem.drop_in_place() };
95 }
96 if self.len != 0 {
97 let layout = Layout::array::<T>(self.len).unwrap();
99 unsafe { std::alloc::dealloc(self.array.cast(), layout) }
100 }
101 }
102}