@@ -11,9 +11,11 @@ use super::objstr;
11
11
use super :: objtype;
12
12
use num_bigint:: ToBigInt ;
13
13
use num_traits:: ToPrimitive ;
14
+ use std:: cell:: { Ref , RefMut } ;
15
+ use std:: ops:: { Deref , DerefMut } ;
14
16
15
17
// set_item:
16
- pub fn set_item (
18
+ fn set_item (
17
19
vm : & mut VirtualMachine ,
18
20
l : & mut Vec < PyObjectRef > ,
19
21
idx : PyObjectRef ,
@@ -32,12 +34,26 @@ pub fn set_item(
32
34
}
33
35
}
34
36
35
- pub fn get_elements ( obj : & PyObjectRef ) -> Vec < PyObjectRef > {
36
- if let PyObjectKind :: List { elements } = & obj. borrow ( ) . kind {
37
- elements. to_vec ( )
38
- } else {
39
- panic ! ( "Cannot extract list elements from non-list" ) ;
40
- }
37
+ pub fn get_elements < ' a > ( obj : & ' a PyObjectRef ) -> impl Deref < Target = Vec < PyObjectRef > > + ' a {
38
+ Ref :: map ( obj. borrow ( ) , |x| {
39
+ if let PyObjectKind :: List { ref elements } = x. kind {
40
+ elements
41
+ } else {
42
+ panic ! ( "Cannot extract list elements from non-list" ) ;
43
+ }
44
+ } )
45
+ }
46
+
47
+ pub fn get_mut_elements < ' a > ( obj : & ' a PyObjectRef ) -> impl DerefMut < Target = Vec < PyObjectRef > > + ' a {
48
+ RefMut :: map ( obj. borrow_mut ( ) , |x| {
49
+ if let PyObjectKind :: List { ref mut elements } = x. kind {
50
+ elements
51
+ } else {
52
+ panic ! ( "Cannot extract list elements from non-list" ) ;
53
+ // TODO: raise proper error?
54
+ // Err(vm.new_type_error("list.append is called with no list".to_string()))
55
+ }
56
+ } )
41
57
}
42
58
43
59
fn list_new ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -76,7 +92,7 @@ fn list_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
76
92
let result = if objtype:: isinstance ( other, & vm. ctx . list_type ( ) ) {
77
93
let zelf = get_elements ( zelf) ;
78
94
let other = get_elements ( other) ;
79
- seq_equal ( vm, zelf, other) ?
95
+ seq_equal ( vm, & zelf, & other) ?
80
96
} else {
81
97
false
82
98
} ;
@@ -105,7 +121,7 @@ fn list_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
105
121
106
122
let elements = get_elements ( o) ;
107
123
let mut str_parts = vec ! [ ] ;
108
- for elem in elements {
124
+ for elem in elements. iter ( ) {
109
125
let s = vm. to_repr ( elem) ?;
110
126
str_parts. push ( objstr:: get_value ( & s) ) ;
111
127
}
@@ -121,25 +137,17 @@ pub fn list_append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
121
137
args,
122
138
required = [ ( list, Some ( vm. ctx. list_type( ) ) ) , ( x, None ) ]
123
139
) ;
124
- let mut list_obj = list. borrow_mut ( ) ;
125
- if let PyObjectKind :: List { ref mut elements } = list_obj. kind {
126
- elements. push ( x. clone ( ) ) ;
127
- Ok ( vm. get_none ( ) )
128
- } else {
129
- Err ( vm. new_type_error ( "list.append is called with no list" . to_string ( ) ) )
130
- }
140
+ let mut elements = get_mut_elements ( list) ;
141
+ elements. push ( x. clone ( ) ) ;
142
+ Ok ( vm. get_none ( ) )
131
143
}
132
144
133
145
fn list_clear ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
134
146
trace ! ( "list.clear called with: {:?}" , args) ;
135
147
arg_check ! ( vm, args, required = [ ( list, Some ( vm. ctx. list_type( ) ) ) ] ) ;
136
- let mut list_obj = list. borrow_mut ( ) ;
137
- if let PyObjectKind :: List { ref mut elements } = list_obj. kind {
138
- elements. clear ( ) ;
139
- Ok ( vm. get_none ( ) )
140
- } else {
141
- Err ( vm. new_type_error ( "list.clear is called with no list" . to_string ( ) ) )
142
- }
148
+ let mut elements = get_mut_elements ( list) ;
149
+ elements. clear ( ) ;
150
+ Ok ( vm. get_none ( ) )
143
151
}
144
152
145
153
pub fn list_extend ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -149,13 +157,9 @@ pub fn list_extend(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
149
157
required = [ ( list, Some ( vm. ctx. list_type( ) ) ) , ( x, None ) ]
150
158
) ;
151
159
let mut new_elements = vm. extract_elements ( x) ?;
152
- let mut list_obj = list. borrow_mut ( ) ;
153
- if let PyObjectKind :: List { ref mut elements } = list_obj. kind {
154
- elements. append ( & mut new_elements) ;
155
- Ok ( vm. get_none ( ) )
156
- } else {
157
- Err ( vm. new_type_error ( "list.extend is called with no list" . to_string ( ) ) )
158
- }
160
+ let mut elements = get_mut_elements ( list) ;
161
+ elements. append ( & mut new_elements) ;
162
+ Ok ( vm. get_none ( ) )
159
163
}
160
164
161
165
fn list_len ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -168,13 +172,9 @@ fn list_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
168
172
fn list_reverse ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
169
173
trace ! ( "list.reverse called with: {:?}" , args) ;
170
174
arg_check ! ( vm, args, required = [ ( list, Some ( vm. ctx. list_type( ) ) ) ] ) ;
171
- let mut list_obj = list. borrow_mut ( ) ;
172
- if let PyObjectKind :: List { ref mut elements } = list_obj. kind {
173
- elements. reverse ( ) ;
174
- Ok ( vm. get_none ( ) )
175
- } else {
176
- Err ( vm. new_type_error ( "list.reverse is called with no list" . to_string ( ) ) )
177
- }
175
+ let mut elements = get_mut_elements ( list) ;
176
+ elements. reverse ( ) ;
177
+ Ok ( vm. get_none ( ) )
178
178
}
179
179
180
180
fn list_contains ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -208,12 +208,23 @@ fn list_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
208
208
get_item ( vm, list, & get_elements ( list) , needle. clone ( ) )
209
209
}
210
210
211
+ fn list_setitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
212
+ arg_check ! (
213
+ vm,
214
+ args,
215
+ required = [ ( list, Some ( vm. ctx. list_type( ) ) ) , ( key, None ) , ( value, None ) ]
216
+ ) ;
217
+ let mut elements = get_mut_elements ( list) ;
218
+ set_item ( vm, & mut elements, key. clone ( ) , value. clone ( ) )
219
+ }
220
+
211
221
pub fn init ( context : & PyContext ) {
212
222
let ref list_type = context. list_type ;
213
223
list_type. set_attr ( "__add__" , context. new_rustfunc ( list_add) ) ;
214
224
list_type. set_attr ( "__contains__" , context. new_rustfunc ( list_contains) ) ;
215
225
list_type. set_attr ( "__eq__" , context. new_rustfunc ( list_eq) ) ;
216
226
list_type. set_attr ( "__getitem__" , context. new_rustfunc ( list_getitem) ) ;
227
+ list_type. set_attr ( "__setitem__" , context. new_rustfunc ( list_setitem) ) ;
217
228
list_type. set_attr ( "__len__" , context. new_rustfunc ( list_len) ) ;
218
229
list_type. set_attr ( "__new__" , context. new_rustfunc ( list_new) ) ;
219
230
list_type. set_attr ( "__repr__" , context. new_rustfunc ( list_repr) ) ;
0 commit comments