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