ext_php_rs/zend/
linked_list.rs

1use 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}