1
- use std:: collections:: HashMap ;
2
1
use std:: fmt;
3
2
4
3
use serde;
5
- use serde:: de:: Visitor ;
4
+ use serde:: de:: { DeserializeSeed , Visitor } ;
6
5
use serde:: ser:: { SerializeMap , SerializeSeq } ;
7
6
use serde_json;
8
7
9
8
use super :: super :: obj:: { objdict, objfloat, objint, objlist, objstr, objtuple, objtype} ;
10
9
use super :: super :: objbool;
11
10
use super :: super :: pyobject:: {
12
- DictProtocol , PyContext , PyFuncArgs , PyObject , PyObjectKind , PyObjectRef , PyResult ,
13
- TypeProtocol ,
11
+ DictProtocol , PyContext , PyFuncArgs , PyObjectKind , PyObjectRef , PyResult , TypeProtocol ,
14
12
} ;
15
13
use super :: super :: VirtualMachine ;
16
14
@@ -75,128 +73,123 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
75
73
}
76
74
}
77
75
78
- struct PyObjectKindVisitor ;
79
-
80
- impl < ' de > Visitor < ' de > for PyObjectKindVisitor {
81
- type Value = PyObjectKind ;
76
+ // This object is used as the seed for deserialization so we have access to the PyContext for type
77
+ // creation
78
+ #[ derive( Clone ) ]
79
+ struct PyObjectDeserializer < ' c > {
80
+ ctx : & ' c PyContext ,
81
+ }
82
82
83
- fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
84
- formatter. write_str ( "a type that can deserialise in Python" )
85
- }
83
+ impl < ' de > serde:: de:: DeserializeSeed < ' de > for PyObjectDeserializer < ' de > {
84
+ type Value = PyObjectRef ;
86
85
87
- fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
86
+ fn deserialize < D > ( self , deserializer : D ) -> Result < Self :: Value , D :: Error >
88
87
where
89
- E : serde:: de :: Error ,
88
+ D : serde:: Deserializer < ' de > ,
90
89
{
91
- Ok ( PyObjectKind :: String {
92
- value : value. to_string ( ) ,
93
- } )
94
- }
90
+ impl < ' de > Visitor < ' de > for PyObjectDeserializer < ' de > {
91
+ type Value = PyObjectRef ;
95
92
96
- fn visit_string < E > ( self , value : String ) -> Result < Self :: Value , E >
97
- where
98
- E : serde:: de:: Error ,
99
- {
100
- Ok ( PyObjectKind :: String { value } )
101
- }
93
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
94
+ formatter. write_str ( "a type that can deserialise in Python" )
95
+ }
102
96
103
- fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
104
- where
105
- E : serde:: de:: Error ,
106
- {
107
- // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
108
- // implement those for now
109
- use std:: i32;
110
- if value >= i32:: MIN as i64 && value <= i32:: MAX as i64 {
111
- Ok ( PyObjectKind :: Integer {
112
- value : value as i32 ,
113
- } )
114
- } else {
115
- Err ( E :: custom ( format ! ( "i64 out of range: {}" , value) ) )
116
- }
117
- }
97
+ fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
98
+ where
99
+ E : serde:: de:: Error ,
100
+ {
101
+ Ok ( self . ctx . new_str ( value. to_string ( ) ) )
102
+ }
118
103
119
- fn visit_u64 < E > ( self , value : u64 ) -> Result < Self :: Value , E >
120
- where
121
- E : serde:: de:: Error ,
122
- {
123
- // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
124
- // implement those for now
125
- use std:: i32;
126
- if value <= i32:: MAX as u64 {
127
- Ok ( PyObjectKind :: Integer {
128
- value : value as i32 ,
129
- } )
130
- } else {
131
- Err ( E :: custom ( format ! ( "u64 out of range: {}" , value) ) )
132
- }
133
- }
104
+ fn visit_string < E > ( self , value : String ) -> Result < Self :: Value , E >
105
+ where
106
+ E : serde:: de:: Error ,
107
+ {
108
+ Ok ( self . ctx . new_str ( value) )
109
+ }
134
110
135
- fn visit_f64 < E > ( self , value : f64 ) -> Result < Self :: Value , E >
136
- where
137
- E : serde:: de:: Error ,
138
- {
139
- Ok ( PyObjectKind :: Float { value } )
140
- }
111
+ fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
112
+ where
113
+ E : serde:: de:: Error ,
114
+ {
115
+ // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
116
+ // implement those for now
117
+ use std:: i32;
118
+ if value >= i32:: MIN as i64 && value <= i32:: MAX as i64 {
119
+ Ok ( self . ctx . new_int ( value as i32 ) )
120
+ } else {
121
+ Err ( E :: custom ( format ! ( "i64 out of range: {}" , value) ) )
122
+ }
123
+ }
141
124
142
- fn visit_bool < E > ( self , value : bool ) -> Result < Self :: Value , E >
143
- where
144
- E : serde:: de:: Error ,
145
- {
146
- Ok ( PyObjectKind :: Integer {
147
- value : if value { 1 } else { 0 } ,
148
- } )
149
- }
125
+ fn visit_u64 < E > ( self , value : u64 ) -> Result < Self :: Value , E >
126
+ where
127
+ E : serde:: de:: Error ,
128
+ {
129
+ // The JSON deserialiser always uses the i64/u64 deserialisers, so we only need to
130
+ // implement those for now
131
+ use std:: i32;
132
+ if value <= i32:: MAX as u64 {
133
+ Ok ( self . ctx . new_int ( value as i32 ) )
134
+ } else {
135
+ Err ( E :: custom ( format ! ( "u64 out of range: {}" , value) ) )
136
+ }
137
+ }
150
138
151
- fn visit_seq < A > ( self , mut access : A ) -> Result < Self :: Value , A :: Error >
152
- where
153
- A : serde:: de:: SeqAccess < ' de > ,
154
- {
155
- let mut seq = Vec :: with_capacity ( access. size_hint ( ) . unwrap_or ( 0 ) ) ;
156
- while let Some ( value) = access. next_element ( ) ? {
157
- seq. push (
158
- PyObject {
159
- kind : value,
160
- typ : None , // TODO: Determine the effect this None will have
161
- } . into_ref ( ) ,
162
- ) ;
163
- }
164
- Ok ( PyObjectKind :: List { elements : seq } )
165
- }
139
+ fn visit_f64 < E > ( self , value : f64 ) -> Result < Self :: Value , E >
140
+ where
141
+ E : serde:: de:: Error ,
142
+ {
143
+ Ok ( self . ctx . new_float ( value) )
144
+ }
166
145
167
- fn visit_map < M > ( self , mut access : M ) -> Result < Self :: Value , M :: Error >
168
- where
169
- M : serde:: de:: MapAccess < ' de > ,
170
- {
171
- let mut map = HashMap :: with_capacity ( access. size_hint ( ) . unwrap_or ( 0 ) ) ;
172
-
173
- while let Some ( ( key, value) ) = access. next_entry ( ) ? {
174
- map. insert (
175
- key,
176
- PyObject {
177
- kind : value,
178
- typ : None , // TODO: Determine the effect this None will have
179
- } . into_ref ( ) ,
180
- ) ;
181
- }
146
+ fn visit_bool < E > ( self , value : bool ) -> Result < Self :: Value , E >
147
+ where
148
+ E : serde:: de:: Error ,
149
+ {
150
+ Ok ( self . ctx . new_bool ( value) )
151
+ }
182
152
183
- Ok ( PyObjectKind :: Dict { elements : map } )
184
- }
153
+ fn visit_seq < A > ( self , mut access : A ) -> Result < Self :: Value , A :: Error >
154
+ where
155
+ A : serde:: de:: SeqAccess < ' de > ,
156
+ {
157
+ let mut seq = Vec :: with_capacity ( access. size_hint ( ) . unwrap_or ( 0 ) ) ;
158
+ while let Some ( value) = access. next_element_seed ( self . clone ( ) ) ? {
159
+ seq. push ( value) ;
160
+ }
161
+ Ok ( self . ctx . new_list ( seq) )
162
+ }
185
163
186
- fn visit_unit < E > ( self ) -> Result < Self :: Value , E >
187
- where
188
- E : serde:: de:: Error ,
189
- {
190
- Ok ( PyObjectKind :: None )
191
- }
192
- }
164
+ fn visit_map < M > ( self , mut access : M ) -> Result < Self :: Value , M :: Error >
165
+ where
166
+ M : serde:: de:: MapAccess < ' de > ,
167
+ {
168
+ let dict = self . ctx . new_dict ( ) ;
169
+ // TODO: Given keys must be strings, we can probably do something more efficient
170
+ // than wrapping the given object up and then unwrapping it to determine whether or
171
+ // not it is a string
172
+ while let Some ( ( key_obj, value) ) =
173
+ access. next_entry_seed ( self . clone ( ) , self . clone ( ) ) ?
174
+ {
175
+ let key = match key_obj. borrow ( ) . kind {
176
+ PyObjectKind :: String { ref value } => value. clone ( ) ,
177
+ _ => unimplemented ! ( "map keys must be strings" ) ,
178
+ } ;
179
+ dict. set_item ( & key, value) ;
180
+ }
181
+ Ok ( dict)
182
+ }
193
183
194
- impl < ' de > serde:: Deserialize < ' de > for PyObjectKind {
195
- fn deserialize < D > ( deserializer : D ) -> Result < PyObjectKind , D :: Error >
196
- where
197
- D : serde:: Deserializer < ' de > ,
198
- {
199
- deserializer. deserialize_any ( PyObjectKindVisitor )
184
+ fn visit_unit < E > ( self ) -> Result < Self :: Value , E >
185
+ where
186
+ E : serde:: de:: Error ,
187
+ {
188
+ Ok ( self . ctx . none . clone ( ) )
189
+ }
190
+ }
191
+
192
+ deserializer. deserialize_any ( self . clone ( ) )
200
193
}
201
194
}
202
195
@@ -216,11 +209,14 @@ fn loads(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
216
209
// TODO: Implement non-trivial deserialisation case
217
210
arg_check ! ( vm, args, required = [ ( string, Some ( vm. ctx. str_type( ) ) ) ] ) ;
218
211
// TODO: Raise an exception for deserialisation errors
219
- let kind: PyObjectKind = match string. borrow ( ) . kind {
220
- PyObjectKind :: String { ref value } => serde_json:: from_str ( & value) . unwrap ( ) ,
212
+ let de = PyObjectDeserializer { ctx : & vm. ctx } ;
213
+ // TODO: Support deserializing string sub-classes
214
+ Ok ( match string. borrow ( ) . kind {
215
+ PyObjectKind :: String { ref value } => de
216
+ . deserialize ( & mut serde_json:: Deserializer :: from_str ( & value) )
217
+ . unwrap ( ) ,
221
218
_ => unimplemented ! ( "json.loads only handles strings" ) ,
222
- } ;
223
- Ok ( PyObject :: new ( kind, vm. get_type ( ) ) )
219
+ } )
224
220
}
225
221
226
222
pub fn mk_module ( ctx : & PyContext ) -> PyObjectRef {
0 commit comments