@@ -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
637637impl < ' 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
664664impl < ' 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
0 commit comments