Skip to content

Commit 91dcc38

Browse files
committed
Refactor
1 parent 3418b04 commit 91dcc38

File tree

3 files changed

+56
-52
lines changed

3 files changed

+56
-52
lines changed

src/types/array.rs

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -576,13 +576,13 @@ pub struct Iter<'a> {
576576
}
577577

578578
#[derive(Debug, PartialEq)]
579-
pub enum ArrayKey<'a> {
579+
pub enum ArrayKey {
580580
Long(i64),
581-
String(&'a str),
581+
String(String),
582582
}
583583

584584
/// Represent the key of a PHP array, which can be either a long or a string.
585-
impl<'a> ArrayKey<'a> {
585+
impl ArrayKey {
586586
/// Check if the key is an integer.
587587
///
588588
/// # Returns
@@ -596,7 +596,7 @@ impl<'a> ArrayKey<'a> {
596596
}
597597
}
598598

599-
impl<'a> Display for ArrayKey<'a> {
599+
impl Display for ArrayKey {
600600
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
601601
match self {
602602
ArrayKey::Long(key) => write!(f, "{}", key),
@@ -605,17 +605,17 @@ impl<'a> Display for ArrayKey<'a> {
605605
}
606606
}
607607

608-
impl<'a> FromZval<'_> for ArrayKey<'a> {
608+
impl<'a> FromZval<'a> for ArrayKey {
609609
const TYPE: DataType = DataType::String;
610610

611-
fn from_zval(zval: &Zval) -> Option<Self> {
611+
fn from_zval(zval: &'a Zval) -> Option<Self> {
612612
if let Some(key) = zval.long() {
613613
return Some(ArrayKey::Long(key));
614614
}
615-
if let Some(key) = zval.str() {
615+
if let Some(key) = zval.string() {
616616
return Some(ArrayKey::String(key));
617617
}
618-
return None;
618+
None
619619
}
620620
}
621621

@@ -635,7 +635,7 @@ impl<'a> Iter<'a> {
635635
}
636636

637637
impl<'a> IntoIterator for &'a ZendHashTable {
638-
type Item = (ArrayKey<'a>, &'a Zval);
638+
type Item = (ArrayKey, &'a Zval);
639639
type IntoIter = Iter<'a>;
640640

641641
/// Returns an iterator over the key(s) and value contained inside the
@@ -662,9 +662,28 @@ impl<'a> IntoIterator for &'a ZendHashTable {
662662
}
663663

664664
impl<'a> Iterator for Iter<'a> {
665-
type Item = (ArrayKey<'a>, &'a Zval);
665+
type Item = (ArrayKey, &'a Zval);
666666

667667
fn next(&mut self) -> Option<Self::Item> {
668+
self.next_zval().map(|(k, v)| (ArrayKey::from_zval(&k).expect("Invalid array key!"), v))
669+
}
670+
671+
fn count(self) -> usize
672+
where
673+
Self: Sized,
674+
{
675+
self.ht.len()
676+
}
677+
}
678+
679+
impl<'a> ExactSizeIterator for Iter<'a> {
680+
fn len(&self) -> usize {
681+
self.ht.len()
682+
}
683+
}
684+
685+
impl<'a> DoubleEndedIterator for Iter<'a> {
686+
fn next_back(&mut self) -> Option<Self::Item> {
668687
let key_type = unsafe {
669688
zend_hash_get_current_key_type_ex(
670689
self.ht as *const ZendHashTable as *mut ZendHashTable,
@@ -677,6 +696,7 @@ impl<'a> Iterator for Iter<'a> {
677696
}
678697

679698
let key = Zval::new();
699+
680700
unsafe {
681701
zend_hash_get_current_key_zval_ex(
682702
self.ht as *const ZendHashTable as *mut ZendHashTable,
@@ -697,32 +717,19 @@ impl<'a> Iterator for Iter<'a> {
697717
};
698718

699719
unsafe {
700-
zend_hash_move_forward_ex(
720+
zend_hash_move_backwards_ex(
701721
self.ht as *const ZendHashTable as *mut ZendHashTable,
702722
&mut self.pos as *mut HashPosition,
703723
)
704724
};
705-
self.current_num += 1;
725+
self.current_num -= 1;
706726

707727
Some((key, value))
708728
}
709-
710-
fn count(self) -> usize
711-
where
712-
Self: Sized,
713-
{
714-
self.ht.len()
715-
}
716-
}
717-
718-
impl<'a> ExactSizeIterator for Iter<'a> {
719-
fn len(&self) -> usize {
720-
self.ht.len()
721-
}
722729
}
723730

724-
impl<'a> DoubleEndedIterator for Iter<'a> {
725-
fn next_back(&mut self) -> Option<Self::Item> {
731+
impl<'a, 'b> Iter<'a> {
732+
pub fn next_zval(&'b mut self) -> Option<(Zval, &'a Zval)> {
726733
let key_type = unsafe {
727734
zend_hash_get_current_key_type_ex(
728735
self.ht as *const ZendHashTable as *mut ZendHashTable,
@@ -734,7 +741,8 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
734741
return None;
735742
}
736743

737-
let key = Zval::new();
744+
let mut key = Zval::new();
745+
738746
unsafe {
739747
zend_hash_get_current_key_zval_ex(
740748
self.ht as *const ZendHashTable as *mut ZendHashTable,
@@ -749,20 +757,19 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
749757
)
750758
};
751759

752-
let r = match ArrayKey::from_zval(&key) {
753-
Some(key) => (key, value),
754-
None => (ArrayKey::Long(self.current_num), value),
755-
};
760+
if !key.is_long() && !key.is_string() {
761+
key.set_long(self.current_num)
762+
}
756763

757764
unsafe {
758-
zend_hash_move_backwards_ex(
765+
zend_hash_move_forward_ex(
759766
self.ht as *const ZendHashTable as *mut ZendHashTable,
760767
&mut self.pos as *mut HashPosition,
761768
)
762769
};
763-
self.current_num -= 1;
770+
self.current_num += 1;
764771

765-
Some(r)
772+
Some((key, value))
766773
}
767774
}
768775

src/types/iterable.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::array::{ArrayKey, Iter as ZendHashTableIter};
1+
use super::array::Iter as ZendHashTableIter;
22
use super::iterator::Iter as ZendIteratorIter;
33
use crate::convert::FromZval;
44
use crate::flags::DataType;
@@ -24,7 +24,7 @@ impl<'a> Iterable<'a> {
2424
}
2525

2626
impl<'a> IntoIterator for &'a mut Iterable<'a> {
27-
type Item = (&'a Zval, &'a Zval);
27+
type Item = (Zval, &'a Zval);
2828
type IntoIter = Iter<'a>;
2929

3030
fn into_iter(self) -> Self::IntoIter {
@@ -55,15 +55,11 @@ pub enum Iter<'a> {
5555
}
5656

5757
impl<'a> Iterator for Iter<'a> {
58-
type Item = (&'a Zval, &'a Zval);
58+
type Item = (Zval, &'a Zval);
5959

6060
fn next(&mut self) -> Option<Self::Item> {
6161
match self {
62-
Iter::Array(array) => match array.next() {
63-
Some((ArrayKey::Long(k), v)) => Zval::new().set_long(v),
64-
Some((ArrayKey::String(k), v)) => Zval::new().set_string(v),
65-
None => None,
66-
},
62+
Iter::Array(array) => array.next_zval(),
6763
Iter::Traversable(traversable) => traversable.next(),
6864
}
6965
}

src/types/iterator.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::convert::{FromZval, FromZvalMut};
1+
use crate::convert::FromZvalMut;
22
use crate::ffi::{zend_object_iterator, ZEND_RESULT_CODE_SUCCESS};
33
use crate::flags::DataType;
44
use crate::types::Zval;
55
use crate::zend::ExecutorGlobals;
6-
use std::fmt::{Debug, Display, Formatter};
6+
use std::fmt::{Debug, Formatter};
77

88
/// A PHP Iterator.
99
///
@@ -124,7 +124,7 @@ impl ZendIterator {
124124
}
125125

126126
impl<'a> IntoIterator for &'a mut ZendIterator {
127-
type Item = (&'a Zval, &'a Zval);
127+
type Item = (Zval, &'a Zval);
128128
type IntoIter = Iter<'a>;
129129

130130
fn into_iter(self) -> Self::IntoIter {
@@ -144,7 +144,7 @@ pub struct Iter<'a> {
144144
}
145145

146146
impl<'a> Iterator for Iter<'a> {
147-
type Item = (&'a Zval, &'a Zval);
147+
type Item = (Zval, &'a Zval);
148148

149149
fn next(&mut self) -> Option<Self::Item> {
150150
// Call next when index > 0, so next is really called at the start of each
@@ -162,11 +162,12 @@ impl<'a> Iterator for Iter<'a> {
162162
let real_index = self.zi.index - 1;
163163

164164
let key = match self.zi.get_current_key() {
165-
None => IterKey::Long(real_index),
166-
Some(key) => match IterKey::from_zval(&key) {
167-
Some(key) => key,
168-
None => IterKey::Long(real_index),
169-
},
165+
None => {
166+
let mut z = Zval::new();
167+
z.set_long(real_index as i64);
168+
z
169+
}
170+
Some(key) => key,
170171
};
171172

172173
self.zi.get_current_data().map(|value| (key, value))

0 commit comments

Comments
 (0)