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