ext_php_rs/types/
iterable.rs1use super::array::Iter as ZendHashTableIter;
2use super::iterator::Iter as ZendIteratorIter;
3use crate::convert::FromZval;
4use crate::flags::DataType;
5use crate::types::{ZendHashTable, ZendIterator, Zval};
6
7#[derive(Debug)]
10pub enum Iterable<'a> {
11 Array(&'a ZendHashTable),
12 Traversable(&'a mut ZendIterator),
13}
14
15impl Iterable<'_> {
16 pub fn iter(&mut self) -> Option<Iter> {
19 match self {
20 Iterable::Array(array) => Some(Iter::Array(array.iter())),
21 Iterable::Traversable(traversable) => Some(Iter::Traversable(traversable.iter()?)),
22 }
23 }
24}
25
26impl<'a> IntoIterator for &'a mut Iterable<'a> {
27 type Item = (Zval, &'a Zval);
28 type IntoIter = Iter<'a>;
29
30 fn into_iter(self) -> Self::IntoIter {
31 self.iter().expect("Could not rewind iterator!")
32 }
33}
34
35impl<'a> FromZval<'a> for Iterable<'a> {
36 const TYPE: DataType = DataType::Iterable;
37
38 fn from_zval(zval: &'a Zval) -> Option<Self> {
39 if let Some(array) = zval.array() {
40 return Some(Iterable::Array(array));
41 }
42
43 if let Some(traversable) = zval.traversable() {
44 return Some(Iterable::Traversable(traversable));
45 }
46
47 None
48 }
49}
50
51pub enum Iter<'a> {
53 Array(ZendHashTableIter<'a>),
54 Traversable(ZendIteratorIter<'a>),
55}
56
57impl<'a> Iterator for Iter<'a> {
58 type Item = (Zval, &'a Zval);
59
60 fn next(&mut self) -> Option<Self::Item> {
61 match self {
62 Iter::Array(array) => array.next_zval(),
63 Iter::Traversable(traversable) => traversable.next(),
64 }
65 }
66}