@@ -7,7 +7,8 @@ use serde_json;
7
7
8
8
use super :: super :: obj:: { objbool, objdict, objfloat, objint, objsequence, objstr, objtype} ;
9
9
use super :: super :: pyobject:: {
10
- PyContext , PyFuncArgs , PyObjectKind , PyObjectRef , PyResult , TypeProtocol ,
10
+ create_type, DictProtocol , PyContext , PyFuncArgs , PyObjectKind , PyObjectRef , PyResult ,
11
+ TypeProtocol ,
11
12
} ;
12
13
use super :: super :: VirtualMachine ;
13
14
use num_bigint:: ToBigInt ;
@@ -69,10 +70,10 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
69
70
} else if let PyObjectKind :: None = self . pyobject . borrow ( ) . kind {
70
71
serializer. serialize_none ( )
71
72
} else {
72
- unimplemented ! (
73
+ Err ( serde :: ser :: Error :: custom ( format ! (
73
74
"Object of type '{:?}' is not serializable" ,
74
75
self . pyobject. typ( )
75
- ) ;
76
+ ) ) )
76
77
}
77
78
}
78
79
}
@@ -190,31 +191,55 @@ impl<'de> serde::de::DeserializeSeed<'de> for PyObjectDeserializer<'de> {
190
191
fn dumps ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
191
192
// TODO: Implement non-trivial serialisation case
192
193
arg_check ! ( vm, args, required = [ ( obj, None ) ] ) ;
193
- // TODO: Raise an exception for serialisation errors
194
- let serializer = PyObjectSerializer {
195
- pyobject : obj,
196
- ctx : & vm. ctx ,
194
+ let res = {
195
+ let serializer = PyObjectSerializer {
196
+ pyobject : obj,
197
+ ctx : & vm. ctx ,
198
+ } ;
199
+ serde_json:: to_string ( & serializer)
197
200
} ;
198
- let string = serde_json :: to_string ( & serializer ) . unwrap ( ) ;
201
+ let string = res . map_err ( |err| vm . new_type_error ( format ! ( "{}" , err ) ) ) ? ;
199
202
Ok ( vm. context ( ) . new_str ( string) )
200
203
}
201
204
202
205
fn loads ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
203
206
// TODO: Implement non-trivial deserialisation case
204
207
arg_check ! ( vm, args, required = [ ( string, Some ( vm. ctx. str_type( ) ) ) ] ) ;
205
- // TODO: Raise an exception for deserialisation errors
206
- let de = PyObjectDeserializer { ctx : & vm. ctx } ;
207
- // TODO: Support deserializing string sub-classes
208
- Ok ( de
209
- . deserialize ( & mut serde_json:: Deserializer :: from_str ( & objstr:: get_value (
208
+ let res = {
209
+ let de = PyObjectDeserializer { ctx : & vm. ctx } ;
210
+ // TODO: Support deserializing string sub-classes
211
+ de. deserialize ( & mut serde_json:: Deserializer :: from_str ( & objstr:: get_value (
210
212
& string,
211
213
) ) )
212
- . unwrap ( ) )
214
+ } ;
215
+
216
+ res. map_err ( |err| {
217
+ let json_decode_error = vm
218
+ . sys_module
219
+ . get_item ( "modules" )
220
+ . unwrap ( )
221
+ . get_item ( "json" )
222
+ . unwrap ( )
223
+ . get_item ( "JSONDecodeError" )
224
+ . unwrap ( ) ;
225
+ let exc = vm. new_exception ( json_decode_error, format ! ( "{}" , err) ) ;
226
+ vm. ctx . set_item ( & exc, "lineno" , vm. ctx . new_int ( err. line ( ) . into ( ) ) ) ;
227
+ vm. ctx . set_item ( & exc, "colno" , vm. ctx . new_int ( err. column ( ) . into ( ) ) ) ;
228
+ exc
229
+ } )
213
230
}
214
231
215
232
pub fn mk_module ( ctx : & PyContext ) -> PyObjectRef {
216
233
let json_mod = ctx. new_module ( & "json" . to_string ( ) , ctx. new_scope ( None ) ) ;
217
234
ctx. set_attr ( & json_mod, "dumps" , ctx. new_rustfunc ( dumps) ) ;
218
235
ctx. set_attr ( & json_mod, "loads" , ctx. new_rustfunc ( loads) ) ;
236
+ // TODO: Make this a proper type with a constructor
237
+ let json_decode_error = create_type (
238
+ "JSONDecodeError" ,
239
+ & ctx. type_type ,
240
+ & ctx. exceptions . exception_type ,
241
+ & ctx. dict_type ,
242
+ ) ;
243
+ ctx. set_attr ( & json_mod, "JSONDecodeError" , json_decode_error) ;
219
244
json_mod
220
245
}
0 commit comments