@@ -2,8 +2,10 @@ use super::objint;
2
2
use super :: objsequence:: PySliceableSequence ;
3
3
use super :: objtype;
4
4
use crate :: format:: { FormatParseError , FormatPart , FormatString } ;
5
+ use crate :: function:: PyRef ;
5
6
use crate :: pyobject:: {
6
- PyContext , PyFuncArgs , PyObjectPayload , PyObjectRef , PyResult , TypeProtocol ,
7
+ OptArg , PyContext , PyFuncArgs , PyIterable , PyObjectPayload , PyObjectPayload2 , PyObjectRef ,
8
+ PyResult , TypeProtocol ,
7
9
} ;
8
10
use crate :: vm:: VirtualMachine ;
9
11
use num_traits:: ToPrimitive ;
@@ -16,6 +18,74 @@ extern crate unicode_segmentation;
16
18
17
19
use self :: unicode_segmentation:: UnicodeSegmentation ;
18
20
21
+ #[ derive( Clone , Debug ) ]
22
+ pub struct PyString {
23
+ // TODO: shouldn't be public
24
+ pub value : String ,
25
+ }
26
+
27
+ impl PyString {
28
+ pub fn endswith (
29
+ zelf : PyRef < Self > ,
30
+ suffix : PyRef < Self > ,
31
+ start : OptArg < usize > ,
32
+ end : OptArg < usize > ,
33
+ _vm : & mut VirtualMachine ,
34
+ ) -> bool {
35
+ let start = start. unwrap_or ( 0 ) ;
36
+ let end = end. unwrap_or ( zelf. value . len ( ) ) ;
37
+ zelf. value [ start..end] . ends_with ( & suffix. value )
38
+ }
39
+
40
+ pub fn startswith (
41
+ zelf : PyRef < Self > ,
42
+ prefix : PyRef < Self > ,
43
+ start : OptArg < usize > ,
44
+ end : OptArg < usize > ,
45
+ _vm : & mut VirtualMachine ,
46
+ ) -> bool {
47
+ let start = start. unwrap_or ( 0 ) ;
48
+ let end = end. unwrap_or ( zelf. value . len ( ) ) ;
49
+ zelf. value [ start..end] . starts_with ( & prefix. value )
50
+ }
51
+
52
+ fn upper ( zelf : PyRef < Self > , _vm : & mut VirtualMachine ) -> PyString {
53
+ PyString {
54
+ value : zelf. value . to_uppercase ( ) ,
55
+ }
56
+ }
57
+
58
+ fn lower ( zelf : PyRef < Self > , _vm : & mut VirtualMachine ) -> PyString {
59
+ PyString {
60
+ value : zelf. value . to_lowercase ( ) ,
61
+ }
62
+ }
63
+
64
+ fn join (
65
+ zelf : PyRef < Self > ,
66
+ iterable : PyIterable < PyRef < Self > > ,
67
+ vm : & mut VirtualMachine ,
68
+ ) -> PyResult < PyString > {
69
+ let mut joined = String :: new ( ) ;
70
+
71
+ for ( idx, elem) in iterable. iter ( vm) ?. enumerate ( ) {
72
+ let elem = elem?;
73
+ if idx != 0 {
74
+ joined. push_str ( & zelf. value ) ;
75
+ }
76
+ joined. push_str ( & elem. value )
77
+ }
78
+
79
+ Ok ( PyString { value : joined } )
80
+ }
81
+ }
82
+
83
+ impl PyObjectPayload2 for PyString {
84
+ fn required_type ( ctx : & PyContext ) -> PyObjectRef {
85
+ ctx. str_type ( )
86
+ }
87
+ }
88
+
19
89
pub fn init ( context : & PyContext ) {
20
90
let str_type = & context. str_type ;
21
91
context. set_attr ( & str_type, "__add__" , context. new_rustfunc ( str_add) ) ;
@@ -37,9 +107,9 @@ pub fn init(context: &PyContext) {
37
107
context. set_attr ( & str_type, "__str__" , context. new_rustfunc ( str_str) ) ;
38
108
context. set_attr ( & str_type, "__repr__" , context. new_rustfunc ( str_repr) ) ;
39
109
context. set_attr ( & str_type, "format" , context. new_rustfunc ( str_format) ) ;
40
- context. set_attr ( & str_type, "lower" , context. new_rustfunc ( str_lower ) ) ;
110
+ context. set_attr ( & str_type, "lower" , context. new_rustfunc ( PyString :: lower ) ) ;
41
111
context. set_attr ( & str_type, "casefold" , context. new_rustfunc ( str_casefold) ) ;
42
- context. set_attr ( & str_type, "upper" , context. new_rustfunc ( str_upper ) ) ;
112
+ context. set_attr ( & str_type, "upper" , context. new_rustfunc ( PyString :: upper ) ) ;
43
113
context. set_attr (
44
114
& str_type,
45
115
"capitalize" ,
@@ -50,11 +120,15 @@ pub fn init(context: &PyContext) {
50
120
context. set_attr ( & str_type, "strip" , context. new_rustfunc ( str_strip) ) ;
51
121
context. set_attr ( & str_type, "lstrip" , context. new_rustfunc ( str_lstrip) ) ;
52
122
context. set_attr ( & str_type, "rstrip" , context. new_rustfunc ( str_rstrip) ) ;
53
- context. set_attr ( & str_type, "endswith" , context. new_rustfunc ( str_endswith) ) ;
123
+ context. set_attr (
124
+ & str_type,
125
+ "endswith" ,
126
+ context. new_rustfunc ( PyString :: endswith) ,
127
+ ) ;
54
128
context. set_attr (
55
129
& str_type,
56
130
"startswith" ,
57
- context. new_rustfunc ( str_startswith ) ,
131
+ context. new_rustfunc ( PyString :: startswith ) ,
58
132
) ;
59
133
context. set_attr ( & str_type, "isalnum" , context. new_rustfunc ( str_isalnum) ) ;
60
134
context. set_attr ( & str_type, "isnumeric" , context. new_rustfunc ( str_isnumeric) ) ;
@@ -74,7 +148,7 @@ pub fn init(context: &PyContext) {
74
148
"splitlines" ,
75
149
context. new_rustfunc ( str_splitlines) ,
76
150
) ;
77
- context. set_attr ( & str_type, "join" , context. new_rustfunc ( str_join ) ) ;
151
+ context. set_attr ( & str_type, "join" , context. new_rustfunc ( PyString :: join ) ) ;
78
152
context. set_attr ( & str_type, "find" , context. new_rustfunc ( str_find) ) ;
79
153
context. set_attr ( & str_type, "rfind" , context. new_rustfunc ( str_rfind) ) ;
80
154
context. set_attr ( & str_type, "index" , context. new_rustfunc ( str_index) ) ;
@@ -103,19 +177,11 @@ pub fn init(context: &PyContext) {
103
177
}
104
178
105
179
pub fn get_value ( obj : & PyObjectRef ) -> String {
106
- if let PyObjectPayload :: String { value } = & obj. payload {
107
- value. to_string ( )
108
- } else {
109
- panic ! ( "Inner error getting str" ) ;
110
- }
180
+ obj. payload :: < PyString > ( ) . unwrap ( ) . value . clone ( )
111
181
}
112
182
113
183
pub fn borrow_value ( obj : & PyObjectRef ) -> & str {
114
- if let PyObjectPayload :: String { value } = & obj. payload {
115
- value. as_str ( )
116
- } else {
117
- panic ! ( "Inner error getting str" ) ;
118
- }
184
+ & obj. payload :: < PyString > ( ) . unwrap ( ) . value
119
185
}
120
186
121
187
fn str_eq ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -377,18 +443,6 @@ fn str_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
377
443
}
378
444
}
379
445
380
- fn str_upper ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
381
- arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
382
- let value = get_value ( & s) . to_uppercase ( ) ;
383
- Ok ( vm. ctx . new_str ( value) )
384
- }
385
-
386
- fn str_lower ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
387
- arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
388
- let value = get_value ( & s) . to_lowercase ( ) ;
389
- Ok ( vm. ctx . new_str ( value) )
390
- }
391
-
392
446
fn str_capitalize ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
393
447
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
394
448
let value = get_value ( & s) ;
@@ -467,17 +521,6 @@ fn str_rstrip(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
467
521
Ok ( vm. ctx . new_str ( value) )
468
522
}
469
523
470
- fn str_endswith ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
471
- arg_check ! (
472
- vm,
473
- args,
474
- required = [ ( s, Some ( vm. ctx. str_type( ) ) ) , ( pat, Some ( vm. ctx. str_type( ) ) ) ]
475
- ) ;
476
- let value = get_value ( & s) ;
477
- let pat = get_value ( & pat) ;
478
- Ok ( vm. ctx . new_bool ( value. ends_with ( pat. as_str ( ) ) ) )
479
- }
480
-
481
524
fn str_isidentifier ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
482
525
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
483
526
let value = get_value ( & s) ;
@@ -557,22 +600,6 @@ fn str_zfill(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
557
600
Ok ( vm. ctx . new_str ( new_str) )
558
601
}
559
602
560
- fn str_join ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
561
- arg_check ! (
562
- vm,
563
- args,
564
- required = [ ( s, Some ( vm. ctx. str_type( ) ) ) , ( iterable, None ) ]
565
- ) ;
566
- let value = get_value ( & s) ;
567
- let elements: Vec < String > = vm
568
- . extract_elements ( iterable) ?
569
- . iter ( )
570
- . map ( |w| get_value ( & w) )
571
- . collect ( ) ;
572
- let joined = elements. join ( & value) ;
573
- Ok ( vm. ctx . new_str ( joined) )
574
- }
575
-
576
603
fn str_count ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
577
604
arg_check ! (
578
605
vm,
@@ -862,17 +889,6 @@ fn str_center(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
862
889
Ok ( vm. ctx . new_str ( new_str) )
863
890
}
864
891
865
- fn str_startswith ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
866
- arg_check ! (
867
- vm,
868
- args,
869
- required = [ ( s, Some ( vm. ctx. str_type( ) ) ) , ( pat, Some ( vm. ctx. str_type( ) ) ) ]
870
- ) ;
871
- let value = get_value ( & s) ;
872
- let pat = get_value ( & pat) ;
873
- Ok ( vm. ctx . new_bool ( value. starts_with ( pat. as_str ( ) ) ) )
874
- }
875
-
876
892
fn str_contains ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
877
893
arg_check ! (
878
894
vm,
0 commit comments