@@ -17,11 +17,11 @@ use unicode_xid::UnicodeXID;
1717use super :: objbytes:: PyBytes ;
1818use super :: objdict:: PyDict ;
1919use super :: objfloat;
20- use super :: objint:: { self , PyInt } ;
20+ use super :: objint:: { self , PyInt , PyIntRef } ;
2121use super :: objiter;
2222use super :: objnone:: PyNone ;
2323use super :: objsequence:: PySliceableSequence ;
24- use super :: objslice:: PySlice ;
24+ use super :: objslice:: PySliceRef ;
2525use super :: objtuple;
2626use super :: objtype:: { self , PyClassRef } ;
2727use crate :: cformat:: {
@@ -32,8 +32,8 @@ use crate::format::{FormatParseError, FormatPart, FormatPreconversor, FormatStri
3232use crate :: function:: { single_or_tuple_any, OptionalArg , PyFuncArgs } ;
3333use crate :: pyhash;
3434use crate :: pyobject:: {
35- IdProtocol , IntoPyObject , ItemProtocol , PyClassImpl , PyContext , PyIterable , PyObjectRef , PyRef ,
36- PyResult , PyValue , TryFromObject , TryIntoRef , TypeProtocol ,
35+ Either , IdProtocol , IntoPyObject , ItemProtocol , PyClassImpl , PyContext , PyIterable ,
36+ PyObjectRef , PyRef , PyResult , PyValue , TryFromObject , TryIntoRef , TypeProtocol ,
3737} ;
3838use crate :: vm:: VirtualMachine ;
3939
@@ -229,8 +229,34 @@ impl PyString {
229229 }
230230
231231 #[ pymethod( name = "__getitem__" ) ]
232- fn getitem ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
233- subscript ( vm, & self . value , needle)
232+ fn getitem ( & self , needle : Either < PyIntRef , PySliceRef > , vm : & VirtualMachine ) -> PyResult {
233+ match needle {
234+ Either :: A ( pos) => match pos. as_bigint ( ) . to_isize ( ) {
235+ Some ( pos) => {
236+ let index: usize = if pos. is_negative ( ) {
237+ ( self . value . chars ( ) . count ( ) as isize + pos) as usize
238+ } else {
239+ pos. abs ( ) as usize
240+ } ;
241+
242+ if let Some ( character) = self . value . chars ( ) . nth ( index) {
243+ Ok ( vm. new_str ( character. to_string ( ) ) )
244+ } else {
245+ Err ( vm. new_index_error ( "string index out of range" . to_string ( ) ) )
246+ }
247+ }
248+ None => Err (
249+ vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) )
250+ ) ,
251+ } ,
252+ Either :: B ( slice) => {
253+ let string = self
254+ . value
255+ . to_string ( )
256+ . get_slice_items ( vm, slice. as_object ( ) ) ?;
257+ Ok ( vm. new_str ( string) )
258+ }
259+ }
234260 }
235261
236262 #[ pymethod( name = "__gt__" ) ]
@@ -292,22 +318,18 @@ impl PyString {
292318 }
293319
294320 #[ pymethod( name = "__mul__" ) ]
295- fn mul ( & self , val : PyObjectRef , vm : & VirtualMachine ) -> PyResult < String > {
296- if !objtype:: isinstance ( & val, & vm. ctx . int_type ( ) ) {
297- return Err ( vm. new_type_error ( format ! ( "Cannot multiply {} and {}" , self , val) ) ) ;
298- }
299- objint:: get_value ( & val)
300- . to_isize ( )
301- . map ( |multiplier| multiplier. max ( 0 ) )
302- . and_then ( |multiplier| multiplier. to_usize ( ) )
321+ fn mul ( & self , multiplier : isize , vm : & VirtualMachine ) -> PyResult < String > {
322+ multiplier
323+ . max ( 0 )
324+ . to_usize ( )
303325 . map ( |multiplier| self . value . repeat ( multiplier) )
304326 . ok_or_else ( || {
305327 vm. new_overflow_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) )
306328 } )
307329 }
308330
309331 #[ pymethod( name = "__rmul__" ) ]
310- fn rmul ( & self , val : PyObjectRef , vm : & VirtualMachine ) -> PyResult < String > {
332+ fn rmul ( & self , val : isize , vm : & VirtualMachine ) -> PyResult < String > {
311333 self . mul ( val, vm)
312334 }
313335
@@ -1575,37 +1597,6 @@ impl PySliceableSequence for String {
15751597 }
15761598}
15771599
1578- pub fn subscript ( vm : & VirtualMachine , value : & str , b : PyObjectRef ) -> PyResult {
1579- if objtype:: isinstance ( & b, & vm. ctx . int_type ( ) ) {
1580- match objint:: get_value ( & b) . to_isize ( ) {
1581- Some ( pos) => {
1582- let index: usize = if pos. is_negative ( ) {
1583- ( value. chars ( ) . count ( ) as isize + pos) as usize
1584- } else {
1585- pos. abs ( ) as usize
1586- } ;
1587-
1588- if let Some ( character) = value. chars ( ) . nth ( index) {
1589- Ok ( vm. new_str ( character. to_string ( ) ) )
1590- } else {
1591- Err ( vm. new_index_error ( "string index out of range" . to_string ( ) ) )
1592- }
1593- }
1594- None => {
1595- Err ( vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_string ( ) ) )
1596- }
1597- }
1598- } else if b. payload :: < PySlice > ( ) . is_some ( ) {
1599- let string = value. to_string ( ) . get_slice_items ( vm, & b) ?;
1600- Ok ( vm. new_str ( string) )
1601- } else {
1602- Err ( vm. new_type_error ( format ! (
1603- "indexing type {:?} with index {:?} is not supported" ,
1604- value, b
1605- ) ) )
1606- }
1607- }
1608-
16091600// help get optional string indices
16101601fn adjust_indices (
16111602 start : OptionalArg < isize > ,
0 commit comments