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),
13 Traversable(&'a mut ZendIterator),
15}
16
17impl Iterable<'_> {
18 #[allow(clippy::iter_not_returning_iterator)]
22 pub fn iter(&mut self) -> Option<Iter<'_>> {
23 match self {
24 Iterable::Array(array) => Some(Iter::Array(array.iter())),
25 Iterable::Traversable(traversable) => Some(Iter::Traversable(traversable.iter()?)),
26 }
27 }
28}
29
30#[allow(clippy::into_iter_without_iter)]
32impl<'a> IntoIterator for &'a mut Iterable<'a> {
33 type Item = (Zval, &'a Zval);
34 type IntoIter = Iter<'a>;
35
36 fn into_iter(self) -> Self::IntoIter {
37 self.iter().expect("Could not rewind iterator!")
38 }
39}
40
41impl<'a> FromZval<'a> for Iterable<'a> {
42 const TYPE: DataType = DataType::Iterable;
43
44 fn from_zval(zval: &'a Zval) -> Option<Self> {
45 if let Some(array) = zval.array() {
46 return Some(Iterable::Array(array));
47 }
48
49 if let Some(traversable) = zval.traversable() {
50 return Some(Iterable::Traversable(traversable));
51 }
52
53 None
54 }
55}
56
57pub enum Iter<'a> {
59 Array(ZendHashTableIter<'a>),
60 Traversable(ZendIteratorIter<'a>),
61}
62
63impl<'a> Iterator for Iter<'a> {
64 type Item = (Zval, &'a Zval);
65
66 fn next(&mut self) -> Option<Self::Item> {
67 match self {
68 Iter::Array(array) => array.next_zval(),
69 Iter::Traversable(traversable) => traversable.next(),
70 }
71 }
72}