@@ -130,16 +130,20 @@ impl PyDictRef {
130
130
self . entries . borrow_mut ( ) . clear ( )
131
131
}
132
132
133
- fn iter ( self , vm : & VirtualMachine ) -> PyDictKeysIteratorRef {
134
- PyDictKeysIteratorRef :: new ( self , vm )
133
+ fn iter ( self , _vm : & VirtualMachine ) -> PyDictKeyIterator {
134
+ PyDictKeyIterator :: new ( self )
135
135
}
136
136
137
- fn values ( self , vm : & VirtualMachine ) -> PyDictValuesIteratorRef {
138
- PyDictValuesIteratorRef :: new ( self , vm )
137
+ fn keys ( self , _vm : & VirtualMachine ) -> PyDictKeys {
138
+ PyDictKeys :: new ( self )
139
139
}
140
140
141
- fn items ( self , vm : & VirtualMachine ) -> PyDictItemsIteratorRef {
142
- PyDictItemsIteratorRef :: new ( self , vm)
141
+ fn values ( self , _vm : & VirtualMachine ) -> PyDictValues {
142
+ PyDictValues :: new ( self )
143
+ }
144
+
145
+ fn items ( self , _vm : & VirtualMachine ) -> PyDictItems {
146
+ PyDictItems :: new ( self )
143
147
}
144
148
145
149
pub fn get_key_value_pairs ( & self ) -> Vec < ( PyObjectRef , PyObjectRef ) > {
@@ -243,116 +247,89 @@ impl ItemProtocol for PyDictRef {
243
247
}
244
248
}
245
249
246
- #[ derive( Debug ) ]
247
- struct PyDictKeysIterator {
248
- pub dict : PyDictRef ,
249
- pub position : Cell < usize > ,
250
- }
251
- type PyDictKeysIteratorRef = PyRef < PyDictKeysIterator > ;
252
-
253
- impl PyDictKeysIteratorRef {
254
- fn new ( dict : PyDictRef , vm : & VirtualMachine ) -> PyDictKeysIteratorRef {
255
- PyDictKeysIterator {
256
- position : Cell :: new ( 0 ) ,
257
- dict,
250
+ macro_rules! dict_iterator {
251
+ ( $name: ident, $iter_name: ident, $class: ident, $iter_class: ident, $result_fn: expr) => {
252
+ #[ derive( Debug ) ]
253
+ struct $name {
254
+ pub dict: PyDictRef ,
258
255
}
259
- . into_ref ( vm)
260
- }
261
256
262
- fn next ( self , vm : & VirtualMachine ) -> PyResult {
263
- match self . dict . entries . borrow ( ) . next_entry ( self . position . get ( ) ) {
264
- Some ( ( new_position, key, _value) ) => {
265
- self . position . set ( new_position) ;
266
- Ok ( key. clone ( ) )
257
+ impl $name {
258
+ fn new( dict: PyDictRef ) -> Self {
259
+ $name { dict: dict }
267
260
}
268
- None => Err ( objiter:: new_stop_iteration ( vm) ) ,
269
- }
270
- }
271
-
272
- fn iter ( self , _vm : & VirtualMachine ) -> Self {
273
- self
274
- }
275
- }
276
-
277
- impl PyValue for PyDictKeysIterator {
278
- fn class ( vm : & VirtualMachine ) -> PyClassRef {
279
- vm. ctx . dictkeysiterator_type . clone ( )
280
- }
281
- }
282
-
283
- #[ derive( Debug ) ]
284
- struct PyDictValuesIterator {
285
- pub dict : PyDictRef ,
286
- pub position : Cell < usize > ,
287
- }
288
- type PyDictValuesIteratorRef = PyRef < PyDictValuesIterator > ;
289
261
290
- impl PyDictValuesIteratorRef {
291
- fn new ( dict : PyDictRef , vm : & VirtualMachine ) -> PyDictValuesIteratorRef {
292
- PyDictValuesIterator {
293
- position : Cell :: new ( 0 ) ,
294
- dict,
262
+ fn iter( & self , _vm: & VirtualMachine ) -> $iter_name {
263
+ $iter_name:: new( self . dict. clone( ) )
264
+ }
295
265
}
296
- . into_ref ( vm)
297
- }
298
266
299
- fn next ( self , vm : & VirtualMachine ) -> PyResult {
300
- match self . dict . entries . borrow ( ) . next_entry ( self . position . get ( ) ) {
301
- Some ( ( new_position, _key, value) ) => {
302
- self . position . set ( new_position) ;
303
- Ok ( value. clone ( ) )
267
+ impl PyValue for $name {
268
+ fn class( vm: & VirtualMachine ) -> PyClassRef {
269
+ vm. ctx. $class. clone( )
304
270
}
305
- None => Err ( objiter:: new_stop_iteration ( vm) ) ,
306
271
}
307
- }
308
-
309
- fn iter ( self , _vm : & VirtualMachine ) -> Self {
310
- self
311
- }
312
- }
313
272
314
- impl PyValue for PyDictValuesIterator {
315
- fn class ( vm : & VirtualMachine ) -> PyClassRef {
316
- vm . ctx . dictvaluesiterator_type . clone ( )
317
- }
318
- }
273
+ # [ derive ( Debug ) ]
274
+ struct $iter_name {
275
+ pub dict : PyDictRef ,
276
+ pub position : Cell < usize > ,
277
+ }
319
278
320
- #[ derive( Debug ) ]
321
- struct PyDictItemsIterator {
322
- pub dict : PyDictRef ,
323
- pub position : Cell < usize > ,
324
- }
279
+ impl $iter_name {
280
+ fn new( dict: PyDictRef ) -> Self {
281
+ $iter_name {
282
+ position: Cell :: new( 0 ) ,
283
+ dict,
284
+ }
285
+ }
325
286
326
- type PyDictItemsIteratorRef = PyRef < PyDictItemsIterator > ;
287
+ fn next( & self , vm: & VirtualMachine ) -> PyResult {
288
+ match self . dict. entries. borrow( ) . next_entry( self . position. get( ) ) {
289
+ Some ( ( new_position, key, value) ) => {
290
+ self . position. set( new_position) ;
291
+ Ok ( $result_fn( vm, key, value) )
292
+ }
293
+ None => Err ( objiter:: new_stop_iteration( vm) ) ,
294
+ }
295
+ }
327
296
328
- impl PyDictItemsIteratorRef {
329
- fn new ( dict : PyDictRef , vm : & VirtualMachine ) -> PyDictItemsIteratorRef {
330
- PyDictItemsIterator {
331
- position : Cell :: new ( 0 ) ,
332
- dict,
297
+ fn iter( zelf: PyRef <Self >, _vm: & VirtualMachine ) -> PyRef <Self > {
298
+ zelf
299
+ }
333
300
}
334
- . into_ref ( vm)
335
- }
336
301
337
- fn next ( self : PyDictItemsIteratorRef , vm : & VirtualMachine ) -> PyResult {
338
- match self . dict . entries . borrow ( ) . next_entry ( self . position . get ( ) ) {
339
- Some ( ( new_position, key, value) ) => {
340
- self . position . set ( new_position) ;
341
- Ok ( vm. ctx . new_tuple ( vec ! [ key. clone( ) , value. clone( ) ] ) )
302
+ impl PyValue for $iter_name {
303
+ fn class( vm: & VirtualMachine ) -> PyClassRef {
304
+ vm. ctx. $iter_class. clone( )
342
305
}
343
- None => Err ( objiter:: new_stop_iteration ( vm) ) ,
344
306
}
345
- }
307
+ } ;
308
+ }
346
309
347
- fn iter ( self , _vm : & VirtualMachine ) -> Self {
348
- self
349
- }
310
+ dict_iterator ! {
311
+ PyDictKeys ,
312
+ PyDictKeyIterator ,
313
+ dictkeys_type,
314
+ dictkeyiterator_type,
315
+ |_vm: & VirtualMachine , key: & PyObjectRef , _value: & PyObjectRef | key. clone( )
350
316
}
351
317
352
- impl PyValue for PyDictItemsIterator {
353
- fn class ( vm : & VirtualMachine ) -> PyClassRef {
354
- vm. ctx . dictitemsiterator_type . clone ( )
355
- }
318
+ dict_iterator ! {
319
+ PyDictValues ,
320
+ PyDictValueIterator ,
321
+ dictvalues_type,
322
+ dictvalueiterator_type,
323
+ |_vm: & VirtualMachine , _key: & PyObjectRef , value: & PyObjectRef | value. clone( )
324
+ }
325
+
326
+ dict_iterator ! {
327
+ PyDictItems ,
328
+ PyDictItemIterator ,
329
+ dictitems_type,
330
+ dictitemiterator_type,
331
+ |vm: & VirtualMachine , key: & PyObjectRef , value: & PyObjectRef |
332
+ vm. ctx. new_tuple( vec![ key. clone( ) , value. clone( ) ] )
356
333
}
357
334
358
335
pub fn init ( context : & PyContext ) {
@@ -371,24 +348,36 @@ pub fn init(context: &PyContext) {
371
348
"values" => context. new_rustfunc( PyDictRef :: values) ,
372
349
"items" => context. new_rustfunc( PyDictRef :: items) ,
373
350
// TODO: separate type. `keys` should be a live view over the collection, not an iterator.
374
- "keys" => context. new_rustfunc( PyDictRef :: iter ) ,
351
+ "keys" => context. new_rustfunc( PyDictRef :: keys ) ,
375
352
"get" => context. new_rustfunc( PyDictRef :: get) ,
376
353
"copy" => context. new_rustfunc( PyDictRef :: copy) ,
377
354
"update" => context. new_rustfunc( PyDictRef :: update) ,
378
355
} ) ;
379
356
380
- extend_class ! ( context, & context. dictkeysiterator_type, {
381
- "__next__" => context. new_rustfunc( PyDictKeysIteratorRef :: next) ,
382
- "__iter__" => context. new_rustfunc( PyDictKeysIteratorRef :: iter) ,
357
+ extend_class ! ( context, & context. dictkeys_type, {
358
+ "__iter__" => context. new_rustfunc( PyDictKeys :: iter) ,
359
+ } ) ;
360
+
361
+ extend_class ! ( context, & context. dictkeyiterator_type, {
362
+ "__next__" => context. new_rustfunc( PyDictKeyIterator :: next) ,
363
+ "__iter__" => context. new_rustfunc( PyDictKeyIterator :: iter) ,
364
+ } ) ;
365
+
366
+ extend_class ! ( context, & context. dictvalues_type, {
367
+ "__iter__" => context. new_rustfunc( PyDictValues :: iter) ,
368
+ } ) ;
369
+
370
+ extend_class ! ( context, & context. dictvalueiterator_type, {
371
+ "__next__" => context. new_rustfunc( PyDictValueIterator :: next) ,
372
+ "__iter__" => context. new_rustfunc( PyDictValueIterator :: iter) ,
383
373
} ) ;
384
374
385
- extend_class ! ( context, & context. dictvaluesiterator_type, {
386
- "__next__" => context. new_rustfunc( PyDictValuesIteratorRef :: next) ,
387
- "__iter__" => context. new_rustfunc( PyDictValuesIteratorRef :: iter) ,
375
+ extend_class ! ( context, & context. dictitems_type, {
376
+ "__iter__" => context. new_rustfunc( PyDictItems :: iter) ,
388
377
} ) ;
389
378
390
- extend_class ! ( context, & context. dictitemsiterator_type , {
391
- "__next__" => context. new_rustfunc( PyDictItemsIteratorRef :: next) ,
392
- "__iter__" => context. new_rustfunc( PyDictItemsIteratorRef :: iter) ,
379
+ extend_class ! ( context, & context. dictitemiterator_type , {
380
+ "__next__" => context. new_rustfunc( PyDictItemIterator :: next) ,
381
+ "__iter__" => context. new_rustfunc( PyDictItemIterator :: iter) ,
393
382
} ) ;
394
383
}
0 commit comments