@@ -15,6 +15,7 @@ use derive_more::From;
15
15
use std:: {
16
16
borrow:: Borrow ,
17
17
convert:: TryInto ,
18
+ ffi:: c_void,
18
19
marker:: PhantomData ,
19
20
mem:: { forget, ManuallyDrop } ,
20
21
ops:: { Deref , DerefMut } ,
@@ -103,7 +104,7 @@ impl ZArr {
103
104
self . len ( ) == 0
104
105
}
105
106
106
- // Get items length.
107
+ /// Get items length.
107
108
#[ inline]
108
109
pub fn len ( & mut self ) -> usize {
109
110
unsafe { zend_array_count ( self . as_mut_ptr ( ) ) . try_into ( ) . unwrap ( ) }
@@ -243,10 +244,11 @@ impl ZArr {
243
244
}
244
245
}
245
246
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) ;
250
252
}
251
253
}
252
254
@@ -366,53 +368,25 @@ impl Drop for ZArray {
366
368
}
367
369
}
368
370
369
- /// Iterator key for [Iter ].
371
+ /// Iterator key for [`ZArr::for_each` ].
370
372
#[ derive( Debug , Clone , PartialEq , From ) ]
371
373
pub enum IterKey < ' a > {
372
374
Index ( u64 ) ,
373
375
ZStr ( & ' a ZStr ) ,
374
376
}
375
377
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) ) ;
416
390
}
417
391
418
392
pub enum Entry < ' a > {
0 commit comments