@@ -240,8 +240,10 @@ impl<T: Clone> PySliceableSequenceMut for Vec<T> {
240
240
}
241
241
242
242
pub trait PySliceableSequence {
243
+ type Item ;
243
244
type Sliced ;
244
245
246
+ fn do_get ( & self , index : usize ) -> Self :: Item ;
245
247
fn do_slice ( & self , range : Range < usize > ) -> Self :: Sliced ;
246
248
fn do_slice_reverse ( & self , range : Range < usize > ) -> Self :: Sliced ;
247
249
fn do_stepped_slice ( & self , range : Range < usize > , step : usize ) -> Self :: Sliced ;
@@ -332,25 +334,53 @@ pub trait PySliceableSequence {
332
334
}
333
335
}
334
336
}
337
+
338
+ fn get_item (
339
+ & self ,
340
+ vm : & VirtualMachine ,
341
+ needle : PyObjectRef ,
342
+ owner_type : & ' static str ,
343
+ ) -> PyResult < Either < Self :: Item , Self :: Sliced > > {
344
+ let needle = SequenceIndex :: try_from_object_for ( vm, needle, owner_type) ?;
345
+ match needle {
346
+ SequenceIndex :: Int ( value) => {
347
+ let pos_index = self . wrap_index ( value) . ok_or_else ( || {
348
+ vm. new_index_error ( format ! ( "{} index out of range" , owner_type) )
349
+ } ) ?;
350
+ Ok ( Either :: A ( self . do_get ( pos_index) ) )
351
+ }
352
+ SequenceIndex :: Slice ( slice) => Ok ( Either :: B ( self . get_slice_items ( vm, & slice) ?) ) ,
353
+ }
354
+ }
335
355
}
336
356
337
357
impl < T : Clone > PySliceableSequence for [ T ] {
358
+ type Item = T ;
338
359
type Sliced = Vec < T > ;
339
360
361
+ #[ inline]
362
+ fn do_get ( & self , index : usize ) -> Self :: Item {
363
+ self [ index] . clone ( )
364
+ }
365
+
366
+ #[ inline]
340
367
fn do_slice ( & self , range : Range < usize > ) -> Self :: Sliced {
341
368
self [ range] . to_vec ( )
342
369
}
343
370
371
+ #[ inline]
344
372
fn do_slice_reverse ( & self , range : Range < usize > ) -> Self :: Sliced {
345
373
let mut slice = self [ range] . to_vec ( ) ;
346
374
slice. reverse ( ) ;
347
375
slice
348
376
}
349
377
378
+ #[ inline]
350
379
fn do_stepped_slice ( & self , range : Range < usize > , step : usize ) -> Self :: Sliced {
351
380
self [ range] . iter ( ) . step_by ( step) . cloned ( ) . collect ( )
352
381
}
353
382
383
+ #[ inline]
354
384
fn do_stepped_slice_reverse ( & self , range : Range < usize > , step : usize ) -> Self :: Sliced {
355
385
self [ range] . iter ( ) . rev ( ) . step_by ( step) . cloned ( ) . collect ( )
356
386
}
@@ -376,8 +406,12 @@ pub enum SequenceIndex {
376
406
Slice ( PySliceRef ) ,
377
407
}
378
408
379
- impl TryFromObject for SequenceIndex {
380
- fn try_from_object ( vm : & VirtualMachine , obj : PyObjectRef ) -> PyResult < Self > {
409
+ impl SequenceIndex {
410
+ fn try_from_object_for (
411
+ vm : & VirtualMachine ,
412
+ obj : PyObjectRef ,
413
+ owner_type : & ' static str ,
414
+ ) -> PyResult < Self > {
381
415
match_class ! ( match obj {
382
416
i @ PyInt => i
383
417
. borrow_value( )
@@ -387,13 +421,20 @@ impl TryFromObject for SequenceIndex {
387
421
. new_index_error( "cannot fit 'int' into an index-sized integer" . to_owned( ) ) ) ,
388
422
s @ PySlice => Ok ( SequenceIndex :: Slice ( s) ) ,
389
423
obj => Err ( vm. new_type_error( format!(
390
- "sequence indices be integers or slices, not {}" ,
391
- obj. class( ) ,
424
+ "{} indices must be integers or slices, not {}" ,
425
+ owner_type,
426
+ obj. lease_class( ) . name,
392
427
) ) ) ,
393
428
} )
394
429
}
395
430
}
396
431
432
+ impl TryFromObject for SequenceIndex {
433
+ fn try_from_object ( vm : & VirtualMachine , obj : PyObjectRef ) -> PyResult < Self > {
434
+ Self :: try_from_object_for ( vm, obj, "sequence" )
435
+ }
436
+ }
437
+
397
438
/// Get the index into a sequence like type. Get it from a python integer
398
439
/// object, accounting for negative index, and out of bounds issues.
399
440
// pub fn get_sequence_index(vm: &VirtualMachine, index: &PyIntRef, length: usize) -> PyResult<usize> {
@@ -455,31 +496,6 @@ pub(crate) fn saturate_index(p: isize, len: usize) -> usize {
455
496
// start..stop
456
497
// }
457
498
458
- pub fn get_item (
459
- vm : & VirtualMachine ,
460
- sequence : & PyObjectRef ,
461
- elements : & [ PyObjectRef ] ,
462
- subscript : PyObjectRef ,
463
- ) -> PyResult < Either < PyObjectRef , Vec < PyObjectRef > > > {
464
- if let Some ( i) = subscript. payload :: < PyInt > ( ) {
465
- let value = i. borrow_value ( ) . to_isize ( ) . ok_or_else ( || {
466
- vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_owned ( ) )
467
- } ) ?;
468
- let pos_index = elements
469
- . wrap_index ( value)
470
- . ok_or_else ( || vm. new_index_error ( "Index out of bounds!" . to_owned ( ) ) ) ?;
471
- Ok ( Either :: A ( elements[ pos_index] . clone ( ) ) )
472
- } else {
473
- let slice = subscript. payload :: < PySlice > ( ) . ok_or_else ( || {
474
- vm. new_type_error ( format ! (
475
- "{} indices must be integers or slices" ,
476
- sequence. lease_class( ) . name
477
- ) )
478
- } ) ?;
479
- Ok ( Either :: B ( elements. get_slice_items ( vm, slice) ?) )
480
- }
481
- }
482
-
483
499
//Check if given arg could be used with PySliceableSequence.saturate_range()
484
500
// pub fn is_valid_slice_arg(
485
501
// arg: OptionalArg<PyObjectRef>,
0 commit comments