11use bstr:: ByteSlice ;
22use num_bigint:: { BigInt , ToBigInt } ;
3- use num_integer:: Integer ;
43use num_traits:: { One , Signed , ToPrimitive , Zero } ;
54use std:: convert:: TryFrom ;
65use std:: ops:: Range ;
@@ -179,25 +178,17 @@ impl ByteInnerFindOptions {
179178#[ derive( FromArgs ) ]
180179pub struct ByteInnerPaddingOptions {
181180 #[ pyarg( positional_only, optional = false ) ]
182- width : PyIntRef ,
181+ width : isize ,
183182 #[ pyarg( positional_only, optional = true ) ]
184- fillbyte : OptionalArg < PyObjectRef > ,
183+ fillchar : OptionalArg < PyObjectRef > ,
185184}
185+
186186impl ByteInnerPaddingOptions {
187- fn get_value ( self , fn_name : & str , len : usize , vm : & VirtualMachine ) -> PyResult < ( u8 , usize ) > {
188- let fillbyte = if let OptionalArg :: Present ( v) = & self . fillbyte {
189- match try_as_byte ( & v) {
190- Some ( x) => {
191- if x. len ( ) == 1 {
192- x[ 0 ]
193- } else {
194- return Err ( vm. new_type_error ( format ! (
195- "{}() argument 2 must be a byte string of length 1, not {}" ,
196- fn_name, & v
197- ) ) ) ;
198- }
199- }
200- None => {
187+ fn get_value ( self , fn_name : & str , vm : & VirtualMachine ) -> PyResult < ( isize , u8 ) > {
188+ let fillchar = if let OptionalArg :: Present ( v) = self . fillchar {
189+ match try_as_byte ( v. clone ( ) ) {
190+ Some ( x) if x. len ( ) == 1 => x[ 0 ] ,
191+ _ => {
201192 return Err ( vm. new_type_error ( format ! (
202193 "{}() argument 2 must be a byte string of length 1, not {}" ,
203194 fn_name, & v
@@ -208,20 +199,7 @@ impl ByteInnerPaddingOptions {
208199 b' ' // default is space
209200 } ;
210201
211- // <0 = no change
212- let width = if let Some ( x) = self . width . as_bigint ( ) . to_usize ( ) {
213- if x <= len {
214- 0
215- } else {
216- x
217- }
218- } else {
219- 0
220- } ;
221-
222- let diff: usize = if width != 0 { width - len } else { 0 } ;
223-
224- Ok ( ( fillbyte, diff) )
202+ Ok ( ( self . width , fillchar) )
225203 }
226204}
227205
@@ -724,59 +702,43 @@ impl PyByteInner {
724702 . collect :: < Vec < u8 > > ( ) )
725703 }
726704
727- pub fn center (
705+ #[ inline]
706+ fn pad (
728707 & self ,
729708 options : ByteInnerPaddingOptions ,
709+ pad : fn ( & [ u8 ] , usize , u8 ) -> Vec < u8 > ,
730710 vm : & VirtualMachine ,
731711 ) -> PyResult < Vec < u8 > > {
732- let ( fillbyte, diff) = options. get_value ( "center" , self . len ( ) , vm) ?;
733-
734- let mut ln: usize = diff / 2 ;
735- let mut rn: usize = ln;
736-
737- if diff. is_odd ( ) && self . len ( ) % 2 == 0 {
738- ln += 1
739- }
740-
741- if diff. is_odd ( ) && self . len ( ) % 2 != 0 {
742- rn += 1
743- }
744-
745- // merge all
746- let mut res = vec ! [ fillbyte; ln] ;
747- res. extend_from_slice ( & self . elements [ ..] ) ;
748- res. extend_from_slice ( & vec ! [ fillbyte; rn] [ ..] ) ;
712+ let ( width, fillchar) = options. get_value ( "center" , vm) ?;
713+ Ok ( if self . len ( ) as isize >= width {
714+ Vec :: from ( & self . elements [ ..] )
715+ } else {
716+ pad ( & self . elements , width as usize , fillchar)
717+ } )
718+ }
749719
750- Ok ( res)
720+ pub fn center (
721+ & self ,
722+ options : ByteInnerPaddingOptions ,
723+ vm : & VirtualMachine ,
724+ ) -> PyResult < Vec < u8 > > {
725+ self . pad ( options, PyCommonString :: < u8 > :: py_center, vm)
751726 }
752727
753728 pub fn ljust (
754729 & self ,
755730 options : ByteInnerPaddingOptions ,
756731 vm : & VirtualMachine ,
757732 ) -> PyResult < Vec < u8 > > {
758- let ( fillbyte, diff) = options. get_value ( "ljust" , self . len ( ) , vm) ?;
759-
760- // merge all
761- let mut res = vec ! [ ] ;
762- res. extend_from_slice ( & self . elements [ ..] ) ;
763- res. extend_from_slice ( & vec ! [ fillbyte; diff] [ ..] ) ;
764-
765- Ok ( res)
733+ self . pad ( options, PyCommonString :: < u8 > :: py_ljust, vm)
766734 }
767735
768736 pub fn rjust (
769737 & self ,
770738 options : ByteInnerPaddingOptions ,
771739 vm : & VirtualMachine ,
772740 ) -> PyResult < Vec < u8 > > {
773- let ( fillbyte, diff) = options. get_value ( "rjust" , self . len ( ) , vm) ?;
774-
775- // merge all
776- let mut res = vec ! [ fillbyte; diff] ;
777- res. extend_from_slice ( & self . elements [ ..] ) ;
778-
779- Ok ( res)
741+ self . pad ( options, PyCommonString :: < u8 > :: py_rjust, vm)
780742 }
781743
782744 pub fn count ( & self , options : ByteInnerFindOptions , vm : & VirtualMachine ) -> PyResult < usize > {
@@ -1259,8 +1221,8 @@ impl PyByteInner {
12591221 }
12601222}
12611223
1262- pub fn try_as_byte ( obj : & PyObjectRef ) -> Option < Vec < u8 > > {
1263- match_class ! ( match obj. clone ( ) {
1224+ pub fn try_as_byte ( obj : PyObjectRef ) -> Option < Vec < u8 > > {
1225+ match_class ! ( match obj {
12641226 i @ PyBytes => Some ( i. get_value( ) . to_vec( ) ) ,
12651227 j @ PyByteArray => Some ( j. borrow_value( ) . elements. to_vec( ) ) ,
12661228 _ => None ,
@@ -1350,15 +1312,25 @@ impl PyCommonStringWrapper<[u8]> for PyByteInner {
13501312const ASCII_WHITESPACES : [ u8 ; 6 ] = [ 0x20 , 0x09 , 0x0a , 0x0c , 0x0d , 0x0b ] ;
13511313
13521314impl PyCommonString < u8 > for [ u8 ] {
1353- fn get_slice ( & self , range : std:: ops:: Range < usize > ) -> & Self {
1315+ type Container = Vec < u8 > ;
1316+
1317+ fn with_capacity ( capacity : usize ) -> Self :: Container {
1318+ Vec :: with_capacity ( capacity)
1319+ }
1320+
1321+ fn get_bytes < ' a > ( & ' a self , range : std:: ops:: Range < usize > ) -> & ' a Self {
13541322 & self [ range]
13551323 }
13561324
13571325 fn is_empty ( & self ) -> bool {
13581326 Self :: is_empty ( self )
13591327 }
13601328
1361- fn len ( & self ) -> usize {
1329+ fn bytes_len ( & self ) -> usize {
1330+ Self :: len ( self )
1331+ }
1332+
1333+ fn chars_len ( & self ) -> usize {
13621334 Self :: len ( self )
13631335 }
13641336
@@ -1407,4 +1379,12 @@ impl PyCommonString<u8> for [u8] {
14071379 }
14081380 splited
14091381 }
1382+
1383+ fn py_pad ( & self , left : usize , right : usize , fill : u8 ) -> Self :: Container {
1384+ let mut u = Vec :: with_capacity ( left + self . len ( ) + right) ;
1385+ u. extend ( std:: iter:: repeat ( fill) . take ( left) ) ;
1386+ u. extend_from_slice ( self ) ;
1387+ u. extend ( std:: iter:: repeat ( fill) . take ( right) ) ;
1388+ u
1389+ }
14101390}
0 commit comments