@@ -6,17 +6,9 @@ use super::super::vm::VirtualMachine;
66use super :: objstr;
77use super :: objtype;
88use num_bigint:: ToBigInt ;
9+ use std:: cell:: { Ref , RefMut } ;
910use 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 } ;
2012
2113pub fn new ( dict_type : PyObjectRef ) -> PyObjectRef {
2214 PyObject :: new (
@@ -27,12 +19,28 @@ pub fn new(dict_type: PyObjectRef) -> PyObjectRef {
2719 )
2820}
2921
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+ } )
3644}
3745
3846fn dict_new ( _vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
@@ -50,13 +58,13 @@ fn dict_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5058
5159 let elements = get_elements ( o) ;
5260 let mut str_parts = vec ! [ ] ;
53- for elem in elements {
61+ for elem in elements. iter ( ) {
5462 let s = vm. to_repr ( & elem. 1 ) ?;
5563 let value_str = objstr:: get_value ( & s) ;
5664 str_parts. push ( format ! ( "{}: {}" , elem. 0 , value_str) ) ;
5765 }
5866
59- let s = format ! ( "{{ {} }}" , str_parts. join( ", " ) ) ;
67+ let s = format ! ( "{{{} }}" , str_parts. join( ", " ) ) ;
6068 Ok ( vm. new_str ( s) )
6169}
6270
@@ -80,7 +88,7 @@ pub fn dict_contains(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8088 Ok ( vm. new_bool ( false ) )
8189}
8290
83- pub fn dict_delitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
91+ fn dict_delitem ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
8492 arg_check ! (
8593 vm,
8694 args,
@@ -94,18 +102,34 @@ pub fn dict_delitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
94102 let needle = objstr:: get_value ( & needle) ;
95103
96104 // 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) ) ) ,
105109 }
106110}
107111
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 {
109133 arg_check ! (
110134 vm,
111135 args,
@@ -143,4 +167,5 @@ pub fn init(context: &PyContext) {
143167 dict_type. set_attr ( "__getitem__" , context. new_rustfunc ( dict_getitem) ) ;
144168 dict_type. set_attr ( "__new__" , context. new_rustfunc ( dict_new) ) ;
145169 dict_type. set_attr ( "__repr__" , context. new_rustfunc ( dict_repr) ) ;
170+ dict_type. set_attr ( "__setitem__" , context. new_rustfunc ( dict_setitem) ) ;
146171}
0 commit comments