@@ -171,14 +171,40 @@ impl ForeignKeyClauses for Column {
171
171
}
172
172
}
173
173
174
- trait FromColumnValue : Sized {
174
+ pub trait FromEntityData : Default {
175
+ type Value : FromColumnValue ;
176
+
177
+ fn insert_entity_data ( & mut self , key : String , v : Self :: Value ) ;
178
+ }
179
+
180
+ impl FromEntityData for Entity {
181
+ type Value = graph:: prelude:: Value ;
182
+
183
+ fn insert_entity_data ( & mut self , key : String , v : Self :: Value ) {
184
+ self . insert ( key, v) ;
185
+ }
186
+ }
187
+
188
+ pub trait FromColumnValue : Sized {
189
+ fn is_null ( & self ) -> bool ;
190
+
191
+ fn from_string ( s : String ) -> Self ;
192
+
175
193
fn from_column_value (
176
194
column_type : & ColumnType ,
177
195
json : serde_json:: Value ,
178
196
) -> Result < Self , StoreError > ;
179
197
}
180
198
181
199
impl FromColumnValue for graph:: prelude:: Value {
200
+ fn is_null ( & self ) -> bool {
201
+ self == & Value :: Null
202
+ }
203
+
204
+ fn from_string ( s : String ) -> Self {
205
+ Value :: String ( s)
206
+ }
207
+
182
208
fn from_column_value (
183
209
column_type : & ColumnType ,
184
210
json : serde_json:: Value ,
@@ -276,36 +302,33 @@ impl EntityData {
276
302
self . entity . clone ( )
277
303
}
278
304
279
- /// Map the `EntityData` to an entity using the schema information
280
- /// in `Layout`
281
- pub fn to_entity ( self , layout : & Layout ) -> Result < Entity , StoreError > {
305
+ /// Map the `EntityData` using the schema information in `Layout`
306
+ pub fn deserialize_with_layout < T : FromEntityData > (
307
+ self ,
308
+ layout : & Layout ,
309
+ ) -> Result < T , StoreError > {
282
310
let table = layout. table_for_entity ( & self . entity ) ?;
283
311
284
312
use serde_json:: Value as j;
285
313
match self . data {
286
314
j:: Object ( map) => {
287
- let mut entity = Entity :: new ( ) ;
288
- entity. insert (
289
- "__typename" . to_owned ( ) ,
290
- graph:: prelude:: Value :: from ( self . entity ) ,
291
- ) ;
315
+ let mut out = T :: default ( ) ;
316
+ out. insert_entity_data ( "__typename" . to_owned ( ) , T :: Value :: from_string ( self . entity ) ) ;
292
317
for ( key, json) in map {
293
318
// Simply ignore keys that do not have an underlying table
294
319
// column; those will be things like the block_range that
295
320
// is used internally for versioning
296
321
if key == "g$parent_id" {
297
- let value =
298
- graph:: prelude:: Value :: from_column_value ( & ColumnType :: String , json) ?;
299
- entity. insert ( "g$parent_id" . to_owned ( ) , value) ;
322
+ let value = T :: Value :: from_column_value ( & ColumnType :: String , json) ?;
323
+ out. insert_entity_data ( "g$parent_id" . to_owned ( ) , value) ;
300
324
} else if let Some ( column) = table. column ( & SqlName :: verbatim ( key) ) {
301
- let value =
302
- graph:: prelude:: Value :: from_column_value ( & column. column_type , json) ?;
303
- if value != Value :: Null {
304
- entity. insert ( column. field . clone ( ) , value) ;
325
+ let value = T :: Value :: from_column_value ( & column. column_type , json) ?;
326
+ if !value. is_null ( ) {
327
+ out. insert_entity_data ( column. field . clone ( ) , value) ;
305
328
}
306
329
}
307
330
}
308
- Ok ( entity )
331
+ Ok ( out )
309
332
}
310
333
_ => unreachable ! (
311
334
"we use `to_json` in our queries, and will therefore always get an object back"
0 commit comments