@@ -17,14 +17,14 @@ use num_traits::cast::ToPrimitive;
17
17
// PyObject serialisation via a proxy object which holds a reference to a VM
18
18
struct PyObjectSerializer < ' s > {
19
19
pyobject : & ' s PyObjectRef ,
20
- ctx : & ' s PyContext ,
20
+ vm : & ' s VirtualMachine ,
21
21
}
22
22
23
23
impl < ' s > PyObjectSerializer < ' s > {
24
24
fn clone_with_object ( & self , pyobject : & ' s PyObjectRef ) -> PyObjectSerializer {
25
25
PyObjectSerializer {
26
26
pyobject,
27
- ctx : self . ctx ,
27
+ vm : self . vm ,
28
28
}
29
29
}
30
30
}
@@ -42,23 +42,23 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
42
42
}
43
43
seq. end ( )
44
44
} ;
45
- if objtype:: isinstance ( self . pyobject , & self . ctx . str_type ( ) ) {
45
+ if objtype:: isinstance ( self . pyobject , & self . vm . ctx . str_type ( ) ) {
46
46
serializer. serialize_str ( & objstr:: get_value ( & self . pyobject ) )
47
- } else if objtype:: isinstance ( self . pyobject , & self . ctx . float_type ( ) ) {
47
+ } else if objtype:: isinstance ( self . pyobject , & self . vm . ctx . float_type ( ) ) {
48
48
serializer. serialize_f64 ( objfloat:: get_value ( self . pyobject ) )
49
- } else if objtype:: isinstance ( self . pyobject , & self . ctx . bool_type ( ) ) {
49
+ } else if objtype:: isinstance ( self . pyobject , & self . vm . ctx . bool_type ( ) ) {
50
50
serializer. serialize_bool ( objbool:: get_value ( self . pyobject ) )
51
- } else if objtype:: isinstance ( self . pyobject , & self . ctx . int_type ( ) ) {
51
+ } else if objtype:: isinstance ( self . pyobject , & self . vm . ctx . int_type ( ) ) {
52
52
let v = objint:: get_value ( self . pyobject ) ;
53
53
serializer. serialize_i64 ( v. to_i64 ( ) . unwrap ( ) )
54
54
// Although this may seem nice, it does not give the right result:
55
55
// v.serialize(serializer)
56
- } else if objtype:: isinstance ( self . pyobject , & self . ctx . list_type ( ) )
57
- || objtype:: isinstance ( self . pyobject , & self . ctx . tuple_type ( ) )
56
+ } else if objtype:: isinstance ( self . pyobject , & self . vm . ctx . list_type ( ) )
57
+ || objtype:: isinstance ( self . pyobject , & self . vm . ctx . tuple_type ( ) )
58
58
{
59
59
let elements = objsequence:: get_elements ( self . pyobject ) ;
60
60
serialize_seq_elements ( serializer, & elements)
61
- } else if objtype:: isinstance ( self . pyobject , & self . ctx . dict_type ( ) ) {
61
+ } else if objtype:: isinstance ( self . pyobject , & self . vm . ctx . dict_type ( ) ) {
62
62
let pairs = objdict:: get_elements ( self . pyobject ) ;
63
63
let mut map = serializer. serialize_map ( Some ( pairs. len ( ) ) ) ?;
64
64
for ( key, e) in pairs. iter ( ) {
@@ -80,7 +80,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
80
80
// creation
81
81
#[ derive( Clone ) ]
82
82
struct PyObjectDeserializer < ' c > {
83
- ctx : & ' c PyContext ,
83
+ vm : & ' c VirtualMachine ,
84
84
}
85
85
86
86
impl < ' de > serde:: de:: DeserializeSeed < ' de > for PyObjectDeserializer < ' de > {
@@ -90,121 +90,121 @@ impl<'de> serde::de::DeserializeSeed<'de> for PyObjectDeserializer<'de> {
90
90
where
91
91
D : serde:: Deserializer < ' de > ,
92
92
{
93
- impl < ' de > Visitor < ' de > for PyObjectDeserializer < ' de > {
94
- type Value = PyObjectRef ;
93
+ deserializer. deserialize_any ( self . clone ( ) )
94
+ }
95
+ }
95
96
96
- fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
97
- formatter. write_str ( "a type that can deserialise in Python" )
98
- }
97
+ impl < ' de > Visitor < ' de > for PyObjectDeserializer < ' de > {
98
+ type Value = PyObjectRef ;
99
99
100
- fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
101
- where
102
- E : serde:: de:: Error ,
103
- {
104
- Ok ( self . ctx . new_str ( value. to_string ( ) ) )
105
- }
100
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
101
+ formatter. write_str ( "a type that can deserialise in Python" )
102
+ }
106
103
107
- fn visit_string < E > ( self , value : String ) -> Result < Self :: Value , E >
108
- where
109
- E : serde:: de:: Error ,
110
- {
111
- Ok ( self . ctx . new_str ( value) )
112
- }
104
+ fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
105
+ where
106
+ E : serde:: de:: Error ,
107
+ {
108
+ Ok ( self . vm . ctx . new_str ( value. to_string ( ) ) )
109
+ }
113
110
114
- fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
115
- where
116
- E : serde:: de:: Error ,
117
- {
118
- // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
119
- // implement those for now
120
- Ok ( self . ctx . new_int ( value) )
121
- }
111
+ fn visit_string < E > ( self , value : String ) -> Result < Self :: Value , E >
112
+ where
113
+ E : serde:: de:: Error ,
114
+ {
115
+ Ok ( self . vm . ctx . new_str ( value) )
116
+ }
122
117
123
- fn visit_u64 < E > ( self , value : u64 ) -> Result < Self :: Value , E >
124
- where
125
- E : serde:: de:: Error ,
126
- {
127
- // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
128
- // implement those for now
129
- Ok ( self . ctx . new_int ( value) )
130
- }
118
+ fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
119
+ where
120
+ E : serde:: de:: Error ,
121
+ {
122
+ // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
123
+ // implement those for now
124
+ Ok ( self . vm . ctx . new_int ( value) )
125
+ }
131
126
132
- fn visit_f64 < E > ( self , value : f64 ) -> Result < Self :: Value , E >
133
- where
134
- E : serde:: de:: Error ,
135
- {
136
- Ok ( self . ctx . new_float ( value) )
137
- }
127
+ fn visit_u64 < E > ( self , value : u64 ) -> Result < Self :: Value , E >
128
+ where
129
+ E : serde:: de:: Error ,
130
+ {
131
+ // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
132
+ // implement those for now
133
+ Ok ( self . vm . ctx . new_int ( value) )
134
+ }
138
135
139
- fn visit_bool < E > ( self , value : bool ) -> Result < Self :: Value , E >
140
- where
141
- E : serde:: de:: Error ,
142
- {
143
- Ok ( self . ctx . new_bool ( value) )
144
- }
136
+ fn visit_f64 < E > ( self , value : f64 ) -> Result < Self :: Value , E >
137
+ where
138
+ E : serde:: de:: Error ,
139
+ {
140
+ Ok ( self . vm . ctx . new_float ( value) )
141
+ }
145
142
146
- fn visit_seq < A > ( self , mut access : A ) -> Result < Self :: Value , A :: Error >
147
- where
148
- A : serde:: de:: SeqAccess < ' de > ,
149
- {
150
- let mut seq = Vec :: with_capacity ( access. size_hint ( ) . unwrap_or ( 0 ) ) ;
151
- while let Some ( value) = access. next_element_seed ( self . clone ( ) ) ? {
152
- seq. push ( value) ;
153
- }
154
- Ok ( self . ctx . new_list ( seq) )
155
- }
143
+ fn visit_bool < E > ( self , value : bool ) -> Result < Self :: Value , E >
144
+ where
145
+ E : serde:: de:: Error ,
146
+ {
147
+ Ok ( self . vm . ctx . new_bool ( value) )
148
+ }
156
149
157
- fn visit_map < M > ( self , mut access : M ) -> Result < Self :: Value , M :: Error >
158
- where
159
- M : serde:: de:: MapAccess < ' de > ,
160
- {
161
- let dict = self . ctx . new_dict ( ) ;
162
- // TODO: Given keys must be strings, we can probably do something more efficient
163
- // than wrapping the given object up and then unwrapping it to determine whether or
164
- // not it is a string
165
- while let Some ( ( key_obj, value) ) =
166
- access. next_entry_seed ( self . clone ( ) , self . clone ( ) ) ?
167
- {
168
- let key = match key_obj. borrow ( ) . payload {
169
- PyObjectPayload :: String { ref value } => value. clone ( ) ,
170
- _ => unimplemented ! ( "map keys must be strings" ) ,
171
- } ;
172
- self . ctx . set_item ( & dict, & key, value) ;
173
- }
174
- Ok ( dict)
175
- }
150
+ fn visit_seq < A > ( self , mut access : A ) -> Result < Self :: Value , A :: Error >
151
+ where
152
+ A : serde:: de:: SeqAccess < ' de > ,
153
+ {
154
+ let mut seq = Vec :: with_capacity ( access. size_hint ( ) . unwrap_or ( 0 ) ) ;
155
+ while let Some ( value) = access. next_element_seed ( self . clone ( ) ) ? {
156
+ seq. push ( value) ;
157
+ }
158
+ Ok ( self . vm . ctx . new_list ( seq) )
159
+ }
176
160
177
- fn visit_unit < E > ( self ) -> Result < Self :: Value , E >
178
- where
179
- E : serde:: de:: Error ,
180
- {
181
- Ok ( self . ctx . none . clone ( ) )
182
- }
161
+ fn visit_map < M > ( self , mut access : M ) -> Result < Self :: Value , M :: Error >
162
+ where
163
+ M : serde:: de:: MapAccess < ' de > ,
164
+ {
165
+ let dict = self . vm . ctx . new_dict ( ) ;
166
+ // TODO: Given keys must be strings, we can probably do something more efficient
167
+ // than wrapping the given object up and then unwrapping it to determine whether or
168
+ // not it is a string
169
+ while let Some ( ( key_obj, value) ) = access. next_entry_seed ( self . clone ( ) , self . clone ( ) ) ? {
170
+ let key = match key_obj. borrow ( ) . payload {
171
+ PyObjectPayload :: String { ref value } => value. clone ( ) ,
172
+ _ => unimplemented ! ( "map keys must be strings" ) ,
173
+ } ;
174
+ self . vm . ctx . set_item ( & dict, & key, value) ;
183
175
}
176
+ Ok ( dict)
177
+ }
184
178
185
- deserializer. deserialize_any ( self . clone ( ) )
179
+ fn visit_unit < E > ( self ) -> Result < Self :: Value , E >
180
+ where
181
+ E : serde:: de:: Error ,
182
+ {
183
+ Ok ( self . vm . ctx . none . clone ( ) )
186
184
}
187
185
}
188
186
189
- fn dumps ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
187
+ /// Implement json.dumps
188
+ fn json_dumps ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
190
189
// TODO: Implement non-trivial serialisation case
191
190
arg_check ! ( vm, args, required = [ ( obj, None ) ] ) ;
192
191
let res = {
193
192
let serializer = PyObjectSerializer {
194
193
pyobject : obj,
195
- ctx : & vm . ctx ,
194
+ vm : vm ,
196
195
} ;
197
196
serde_json:: to_string ( & serializer)
198
197
} ;
199
198
let string = res. map_err ( |err| vm. new_type_error ( format ! ( "{}" , err) ) ) ?;
200
199
Ok ( vm. context ( ) . new_str ( string) )
201
200
}
202
201
203
- fn loads ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
202
+ /// Implement json.loads
203
+ fn json_loads ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
204
204
// TODO: Implement non-trivial deserialisation case
205
205
arg_check ! ( vm, args, required = [ ( string, Some ( vm. ctx. str_type( ) ) ) ] ) ;
206
206
let res = {
207
- let de = PyObjectDeserializer { ctx : & vm . ctx } ;
207
+ let de = PyObjectDeserializer { vm : vm } ;
208
208
// TODO: Support deserializing string sub-classes
209
209
de. deserialize ( & mut serde_json:: Deserializer :: from_str ( & objstr:: get_value (
210
210
& string,
@@ -221,17 +221,17 @@ fn loads(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
221
221
. get_item ( "JSONDecodeError" )
222
222
. unwrap ( ) ;
223
223
let exc = vm. new_exception ( json_decode_error, format ! ( "{}" , err) ) ;
224
- vm. ctx . set_item ( & exc, "lineno" , vm. ctx . new_int ( err. line ( ) ) ) ;
225
- vm. ctx . set_item ( & exc, "colno" , vm. ctx . new_int ( err. column ( ) ) ) ;
224
+ vm. ctx . set_attr ( & exc, "lineno" , vm. ctx . new_int ( err. line ( ) ) ) ;
225
+ vm. ctx . set_attr ( & exc, "colno" , vm. ctx . new_int ( err. column ( ) ) ) ;
226
226
exc
227
227
} )
228
228
}
229
229
230
230
pub fn mk_module ( ctx : & PyContext ) -> PyObjectRef {
231
231
let json_mod = ctx. new_module ( "json" , ctx. new_scope ( None ) ) ;
232
232
233
- ctx. set_attr ( & json_mod, "dumps" , ctx. new_rustfunc ( dumps ) ) ;
234
- ctx. set_attr ( & json_mod, "loads" , ctx. new_rustfunc ( loads ) ) ;
233
+ ctx. set_attr ( & json_mod, "dumps" , ctx. new_rustfunc ( json_dumps ) ) ;
234
+ ctx. set_attr ( & json_mod, "loads" , ctx. new_rustfunc ( json_loads ) ) ;
235
235
236
236
// TODO: Make this a proper type with a constructor
237
237
let json_decode_error = create_type (
0 commit comments