ext_php_rs/zend/
linked_list.rs1use std::marker::PhantomData;
2
3use crate::ffi::{zend_llist, zend_llist_element, zend_llist_get_next_ex};
4
5pub type ZendLinkedList = zend_llist;
6
7impl ZendLinkedList {
8 pub fn iter<T>(&self) -> ZendLinkedListIterator<T> {
9 ZendLinkedListIterator::new(self)
10 }
11}
12
13pub struct ZendLinkedListIterator<'a, T> {
14 list: &'a zend_llist,
15 position: *mut zend_llist_element,
16 _marker: PhantomData<T>,
17}
18
19impl<'a, T> ZendLinkedListIterator<'a, T> {
20 fn new(list: &'a ZendLinkedList) -> Self {
21 ZendLinkedListIterator {
22 list,
23 position: list.head,
24 _marker: PhantomData,
25 }
26 }
27}
28
29impl<'a, T: 'a> Iterator for ZendLinkedListIterator<'a, T> {
30 type Item = &'a T;
31
32 fn next(&mut self) -> Option<Self::Item> {
33 if self.position.is_null() {
34 return None;
35 }
36 let ptr = unsafe { (*self.position).data.as_mut_ptr() };
37 let value = unsafe { &*(ptr as *const T as *mut T) };
38 unsafe {
39 zend_llist_get_next_ex(
40 self.list as *const ZendLinkedList as *mut ZendLinkedList,
41 &mut self.position,
42 )
43 };
44 Some(value)
45 }
46}