@@ -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
- FromPyObject , 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,13 +18,71 @@ extern crate unicode_segmentation;
16
18
17
19
use self :: unicode_segmentation:: UnicodeSegmentation ;
18
20
19
- impl FromPyObject for String {
20
- fn typ ( ctx : & PyContext ) -> Option < PyObjectRef > {
21
- Some ( ctx. str_type ( ) )
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 )
22
38
}
23
39
24
- fn from_pyobject ( obj : PyObjectRef ) -> PyResult < Self > {
25
- Ok ( get_value ( & obj) )
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 ( )
26
86
}
27
87
}
28
88
@@ -47,9 +107,9 @@ pub fn init(context: &PyContext) {
47
107
context. set_attr ( & str_type, "__str__" , context. new_rustfunc ( str_str) ) ;
48
108
context. set_attr ( & str_type, "__repr__" , context. new_rustfunc ( str_repr) ) ;
49
109
context. set_attr ( & str_type, "format" , context. new_rustfunc ( str_format) ) ;
50
- context. set_attr ( & str_type, "lower" , context. new_rustfunc ( str_lower ) ) ;
110
+ context. set_attr ( & str_type, "lower" , context. new_rustfunc ( PyString :: lower ) ) ;
51
111
context. set_attr ( & str_type, "casefold" , context. new_rustfunc ( str_casefold) ) ;
52
- context. set_attr ( & str_type, "upper" , context. new_rustfunc ( str_upper ) ) ;
112
+ context. set_attr ( & str_type, "upper" , context. new_rustfunc ( PyString :: upper ) ) ;
53
113
context. set_attr (
54
114
& str_type,
55
115
"capitalize" ,
@@ -60,11 +120,15 @@ pub fn init(context: &PyContext) {
60
120
context. set_attr ( & str_type, "strip" , context. new_rustfunc ( str_strip) ) ;
61
121
context. set_attr ( & str_type, "lstrip" , context. new_rustfunc ( str_lstrip) ) ;
62
122
context. set_attr ( & str_type, "rstrip" , context. new_rustfunc ( str_rstrip) ) ;
63
- 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
+ ) ;
64
128
context. set_attr (
65
129
& str_type,
66
130
"startswith" ,
67
- context. new_rustfunc ( str_startswith ) ,
131
+ context. new_rustfunc ( PyString :: startswith ) ,
68
132
) ;
69
133
context. set_attr ( & str_type, "isalnum" , context. new_rustfunc ( str_isalnum) ) ;
70
134
context. set_attr ( & str_type, "isnumeric" , context. new_rustfunc ( str_isnumeric) ) ;
@@ -84,7 +148,7 @@ pub fn init(context: &PyContext) {
84
148
"splitlines" ,
85
149
context. new_rustfunc ( str_splitlines) ,
86
150
) ;
87
- context. set_attr ( & str_type, "join" , context. new_rustfunc ( str_join ) ) ;
151
+ context. set_attr ( & str_type, "join" , context. new_rustfunc ( PyString :: join ) ) ;
88
152
context. set_attr ( & str_type, "find" , context. new_rustfunc ( str_find) ) ;
89
153
context. set_attr ( & str_type, "rfind" , context. new_rustfunc ( str_rfind) ) ;
90
154
context. set_attr ( & str_type, "index" , context. new_rustfunc ( str_index) ) ;
@@ -113,19 +177,11 @@ pub fn init(context: &PyContext) {
113
177
}
114
178
115
179
pub fn get_value ( obj : & PyObjectRef ) -> String {
116
- if let PyObjectPayload :: String { value } = & obj. payload {
117
- value. to_string ( )
118
- } else {
119
- panic ! ( "Inner error getting str" ) ;
120
- }
180
+ obj. payload :: < PyString > ( ) . unwrap ( ) . value . clone ( )
121
181
}
122
182
123
183
pub fn borrow_value ( obj : & PyObjectRef ) -> & str {
124
- if let PyObjectPayload :: String { value } = & obj. payload {
125
- value. as_str ( )
126
- } else {
127
- panic ! ( "Inner error getting str" ) ;
128
- }
184
+ & obj. payload :: < PyString > ( ) . unwrap ( ) . value
129
185
}
130
186
131
187
fn str_eq ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -387,18 +443,6 @@ fn str_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
387
443
}
388
444
}
389
445
390
- fn str_upper ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
391
- arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
392
- let value = get_value ( & s) . to_uppercase ( ) ;
393
- Ok ( vm. ctx . new_str ( value) )
394
- }
395
-
396
- fn str_lower ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
397
- arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
398
- let value = get_value ( & s) . to_lowercase ( ) ;
399
- Ok ( vm. ctx . new_str ( value) )
400
- }
401
-
402
446
fn str_capitalize ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
403
447
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
404
448
let value = get_value ( & s) ;
@@ -477,10 +521,6 @@ fn str_rstrip(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
477
521
Ok ( vm. ctx . new_str ( value) )
478
522
}
479
523
480
- fn str_endswith ( _vm : & mut VirtualMachine , zelf : String , suffix : String ) -> bool {
481
- zelf. ends_with ( & suffix)
482
- }
483
-
484
524
fn str_isidentifier ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
485
525
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. str_type( ) ) ) ] ) ;
486
526
let value = get_value ( & s) ;
@@ -560,22 +600,6 @@ fn str_zfill(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
560
600
Ok ( vm. ctx . new_str ( new_str) )
561
601
}
562
602
563
- fn str_join ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
564
- arg_check ! (
565
- vm,
566
- args,
567
- required = [ ( s, Some ( vm. ctx. str_type( ) ) ) , ( iterable, None ) ]
568
- ) ;
569
- let value = get_value ( & s) ;
570
- let elements: Vec < String > = vm
571
- . extract_elements ( iterable) ?
572
- . iter ( )
573
- . map ( |w| get_value ( & w) )
574
- . collect ( ) ;
575
- let joined = elements. join ( & value) ;
576
- Ok ( vm. ctx . new_str ( joined) )
577
- }
578
-
579
603
fn str_count ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
580
604
arg_check ! (
581
605
vm,
@@ -865,17 +889,6 @@ fn str_center(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
865
889
Ok ( vm. ctx . new_str ( new_str) )
866
890
}
867
891
868
- fn str_startswith ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
869
- arg_check ! (
870
- vm,
871
- args,
872
- required = [ ( s, Some ( vm. ctx. str_type( ) ) ) , ( pat, Some ( vm. ctx. str_type( ) ) ) ]
873
- ) ;
874
- let value = get_value ( & s) ;
875
- let pat = get_value ( & pat) ;
876
- Ok ( vm. ctx . new_bool ( value. starts_with ( pat. as_str ( ) ) ) )
877
- }
878
-
879
892
fn str_contains ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
880
893
arg_check ! (
881
894
vm,
0 commit comments