@@ -6,17 +6,9 @@ use super::super::vm::VirtualMachine;
6
6
use super :: objstr;
7
7
use super :: objtype;
8
8
use num_bigint:: ToBigInt ;
9
+ use std:: cell:: { Ref , RefMut } ;
9
10
use std:: collections:: HashMap ;
10
-
11
- pub fn _set_item (
12
- vm : & mut VirtualMachine ,
13
- _d : PyObjectRef ,
14
- _idx : PyObjectRef ,
15
- _obj : PyObjectRef ,
16
- ) -> PyResult {
17
- // TODO: Implement objdict::set_item
18
- Ok ( vm. get_none ( ) )
19
- }
11
+ use std:: ops:: { Deref , DerefMut } ;
20
12
21
13
pub fn new ( dict_type : PyObjectRef ) -> PyObjectRef {
22
14
PyObject :: new (
@@ -27,12 +19,28 @@ pub fn new(dict_type: PyObjectRef) -> PyObjectRef {
27
19
)
28
20
}
29
21
30
- pub fn get_elements ( obj : & PyObjectRef ) -> HashMap < String , PyObjectRef > {
31
- if let PyObjectKind :: Dict { elements } = & obj. borrow ( ) . kind {
32
- elements. clone ( )
33
- } else {
34
- panic ! ( "Cannot extract dict elements" ) ;
35
- }
22
+ pub fn get_elements < ' a > (
23
+ obj : & ' a PyObjectRef ,
24
+ ) -> impl Deref < Target = HashMap < String , PyObjectRef > > + ' a {
25
+ Ref :: map ( obj. borrow ( ) , |py_obj| {
26
+ if let PyObjectKind :: Dict { ref elements } = py_obj. kind {
27
+ elements
28
+ } else {
29
+ panic ! ( "Cannot extract dict elements" ) ;
30
+ }
31
+ } )
32
+ }
33
+
34
+ fn get_mut_elements < ' a > (
35
+ obj : & ' a PyObjectRef ,
36
+ ) -> impl DerefMut < Target = HashMap < String , PyObjectRef > > + ' a {
37
+ RefMut :: map ( obj. borrow_mut ( ) , |py_obj| {
38
+ if let PyObjectKind :: Dict { ref mut elements } = py_obj. kind {
39
+ elements
40
+ } else {
41
+ panic ! ( "Cannot extract dict elements" ) ;
42
+ }
43
+ } )
36
44
}
37
45
38
46
fn dict_new ( _vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -50,13 +58,13 @@ fn dict_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
50
58
51
59
let elements = get_elements ( o) ;
52
60
let mut str_parts = vec ! [ ] ;
53
- for elem in elements {
61
+ for elem in elements. iter ( ) {
54
62
let s = vm. to_repr ( & elem. 1 ) ?;
55
63
let value_str = objstr:: get_value ( & s) ;
56
64
str_parts. push ( format ! ( "{}: {}" , elem. 0 , value_str) ) ;
57
65
}
58
66
59
- let s = format ! ( "{{ {} }}" , str_parts. join( ", " ) ) ;
67
+ let s = format ! ( "{{{} }}" , str_parts. join( ", " ) ) ;
60
68
Ok ( vm. new_str ( s) )
61
69
}
62
70
@@ -80,7 +88,7 @@ pub fn dict_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
80
88
Ok ( vm. new_bool ( false ) )
81
89
}
82
90
83
- pub fn dict_delitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
91
+ fn dict_delitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
84
92
arg_check ! (
85
93
vm,
86
94
args,
@@ -94,18 +102,34 @@ pub fn dict_delitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
94
102
let needle = objstr:: get_value ( & needle) ;
95
103
96
104
// Delete the item:
97
- let mut dict_obj = dict. borrow_mut ( ) ;
98
- if let PyObjectKind :: Dict { ref mut elements } = dict_obj. kind {
99
- match elements. remove ( & needle) {
100
- Some ( _) => Ok ( vm. get_none ( ) ) ,
101
- None => Err ( vm. new_value_error ( format ! ( "Key not found: {}" , needle) ) ) ,
102
- }
103
- } else {
104
- panic ! ( "Cannot extract dict elements" ) ;
105
+ let mut elements = get_mut_elements ( dict) ;
106
+ match elements. remove ( & needle) {
107
+ Some ( _) => Ok ( vm. get_none ( ) ) ,
108
+ None => Err ( vm. new_value_error ( format ! ( "Key not found: {}" , needle) ) ) ,
105
109
}
106
110
}
107
111
108
- pub fn dict_getitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
112
+ fn dict_setitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
113
+ arg_check ! (
114
+ vm,
115
+ args,
116
+ required = [
117
+ ( dict, Some ( vm. ctx. dict_type( ) ) ) ,
118
+ ( needle, Some ( vm. ctx. str_type( ) ) ) ,
119
+ ( value, None )
120
+ ]
121
+ ) ;
122
+
123
+ // What we are looking for:
124
+ let needle = objstr:: get_value ( & needle) ;
125
+
126
+ // Delete the item:
127
+ let mut elements = get_mut_elements ( dict) ;
128
+ elements. insert ( needle, value. clone ( ) ) ;
129
+ Ok ( vm. get_none ( ) )
130
+ }
131
+
132
+ fn dict_getitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
109
133
arg_check ! (
110
134
vm,
111
135
args,
@@ -143,4 +167,5 @@ pub fn init(context: &PyContext) {
143
167
dict_type. set_attr ( "__getitem__" , context. new_rustfunc ( dict_getitem) ) ;
144
168
dict_type. set_attr ( "__new__" , context. new_rustfunc ( dict_new) ) ;
145
169
dict_type. set_attr ( "__repr__" , context. new_rustfunc ( dict_repr) ) ;
170
+ dict_type. set_attr ( "__setitem__" , context. new_rustfunc ( dict_setitem) ) ;
146
171
}
0 commit comments