@@ -15,6 +15,7 @@ use derive_more::From;
1515use std:: {
1616 borrow:: Borrow ,
1717 convert:: TryInto ,
18+ ffi:: c_void,
1819 marker:: PhantomData ,
1920 mem:: { forget, ManuallyDrop } ,
2021 ops:: { Deref , DerefMut } ,
@@ -103,7 +104,7 @@ impl ZArr {
103104 self . len ( ) == 0
104105 }
105106
106- // Get items length.
107+ /// Get items length.
107108 #[ inline]
108109 pub fn len ( & mut self ) -> usize {
109110 unsafe { zend_array_count ( self . as_mut_ptr ( ) ) . try_into ( ) . unwrap ( ) }
@@ -243,10 +244,11 @@ impl ZArr {
243244 }
244245 }
245246
246- pub fn iter ( & self ) -> Iter < ' _ > {
247- Iter {
248- index : 0 ,
249- array : self ,
247+ pub fn for_each < ' a > ( & self , f : impl FnMut ( IterKey < ' a > , & ' a ZVal ) ) {
248+ let mut f: Box < dyn FnMut ( IterKey < ' a > , & ' a ZVal ) > = Box :: new ( f) ;
249+ let f = & mut f as * mut Box < _ > as * mut c_void ;
250+ unsafe {
251+ phper_zend_hash_foreach_key_val ( self . as_ptr ( ) as * mut _ , Some ( for_each_callback) , f) ;
250252 }
251253 }
252254
@@ -366,53 +368,25 @@ impl Drop for ZArray {
366368 }
367369}
368370
369- /// Iterator key for [Iter ].
371+ /// Iterator key for [`ZArr::for_each` ].
370372#[ derive( Debug , Clone , PartialEq , From ) ]
371373pub enum IterKey < ' a > {
372374 Index ( u64 ) ,
373375 ZStr ( & ' a ZStr ) ,
374376}
375377
376- /// Iter created by [ZArr::iter].
377- pub struct Iter < ' a > {
378- index : isize ,
379- array : & ' a ZArr ,
380- }
381-
382- impl < ' a > Iterator for Iter < ' a > {
383- type Item = ( IterKey < ' a > , & ' a ZVal ) ;
384-
385- fn next ( & mut self ) -> Option < Self :: Item > {
386- loop {
387- if self . index >= self . array . inner . nNumUsed as isize {
388- break None ;
389- }
390-
391- unsafe {
392- let bucket = self . array . inner . arData . offset ( self . index ) ;
393-
394- let key = if ( * bucket) . key . is_null ( ) {
395- IterKey :: Index ( ( * bucket) . h )
396- } else {
397- let s = ZStr :: from_ptr ( ( * bucket) . key ) ;
398- IterKey :: ZStr ( s)
399- } ;
400-
401- let val = & mut ( * bucket) . val ;
402- let mut val = ZVal :: from_mut_ptr ( val) ;
403- if val. get_type_info ( ) . is_indirect ( ) {
404- val = ZVal :: from_mut_ptr ( ( * val. as_mut_ptr ( ) ) . value . zv ) ;
405- }
406-
407- self . index += 1 ;
408-
409- if val. get_type_info ( ) . is_undef ( ) {
410- continue ;
411- }
412- break Some ( ( key, val) ) ;
413- }
414- }
415- }
378+ unsafe extern "C" fn for_each_callback (
379+ idx : zend_ulong , key : * mut zend_string , val : * mut zval , argument : * mut c_void ,
380+ ) {
381+ let f = ( argument as * mut Box < dyn FnMut ( IterKey < ' _ > , & ' _ ZVal ) > )
382+ . as_mut ( )
383+ . unwrap ( ) ;
384+ let iter_key = if key. is_null ( ) {
385+ IterKey :: Index ( idx as u64 )
386+ } else {
387+ IterKey :: ZStr ( ZStr :: from_ptr ( key) )
388+ } ;
389+ f ( iter_key, ZVal :: from_ptr ( val) ) ;
416390}
417391
418392pub enum Entry < ' a > {
0 commit comments