1
1
use crate :: error:: Details ;
2
2
use crate :: {
3
- schema:: { NamesRef , Namespace } , util:: { zag_i32, zag_i64} ,
4
- Error ,
5
- Schema ,
3
+ Error , Schema ,
4
+ util:: { zag_i32, zag_i64} ,
6
5
} ;
7
6
use serde:: de:: Visitor ;
7
+ use serde:: { de, forward_to_deserialize_any} ;
8
8
use std:: io:: Read ;
9
+ use std:: slice:: Iter ;
9
10
10
11
pub struct SchemaAwareReadDeserializer < ' s , R : Read > {
11
12
reader : & ' s mut R ,
12
13
root_schema : & ' s Schema ,
13
- _names : & ' s NamesRef < ' s > ,
14
- _enclosing_namespace : Namespace ,
15
14
}
16
15
17
16
impl < ' s , R : Read > SchemaAwareReadDeserializer < ' s , R > {
18
17
#[ allow( dead_code) ] // TODO: remove! It is actually used in reader.rs
19
- pub ( crate ) fn new (
20
- reader : & ' s mut R ,
21
- root_schema : & ' s Schema ,
22
- _names : & ' s NamesRef < ' s > ,
23
- _enclosing_namespace : Namespace ,
24
- ) -> Self {
18
+ pub ( crate ) fn new ( reader : & ' s mut R , root_schema : & ' s Schema ) -> Self {
25
19
Self {
26
20
reader,
27
21
root_schema,
28
- _names,
29
- _enclosing_namespace,
30
22
}
31
23
}
32
24
}
@@ -136,14 +128,14 @@ impl<'de, R: Read> serde::de::Deserializer<'de> for SchemaAwareReadDeserializer<
136
128
where
137
129
V : Visitor < ' de > ,
138
130
{
139
- todo ! ( )
131
+ todo ! ( "Implement deserialization for str" )
140
132
}
141
133
142
134
fn deserialize_string < V > ( self , _visitor : V ) -> Result < V :: Value , Self :: Error >
143
135
where
144
136
V : Visitor < ' de > ,
145
137
{
146
- todo ! ( )
138
+ todo ! ( "Implement deserialization for String" )
147
139
}
148
140
149
141
fn deserialize_bytes < V > ( self , _visitor : V ) -> Result < V :: Value , Self :: Error >
@@ -164,7 +156,7 @@ impl<'de, R: Read> serde::de::Deserializer<'de> for SchemaAwareReadDeserializer<
164
156
where
165
157
V : Visitor < ' de > ,
166
158
{
167
- todo ! ( )
159
+ todo ! ( "Implement deserialization for Option" )
168
160
}
169
161
170
162
fn deserialize_unit < V > ( self , _visitor : V ) -> Result < V :: Value , Self :: Error >
@@ -231,14 +223,18 @@ impl<'de, R: Read> serde::de::Deserializer<'de> for SchemaAwareReadDeserializer<
231
223
232
224
fn deserialize_struct < V > (
233
225
self ,
234
- _name : & ' static str ,
235
- _fields : & ' static [ & ' static str ] ,
236
- _visitor : V ,
226
+ name : & ' static str ,
227
+ fields : & ' static [ & ' static str ] ,
228
+ visitor : V ,
237
229
) -> Result < V :: Value , Self :: Error >
238
230
where
239
231
V : Visitor < ' de > ,
240
232
{
241
- todo ! ( )
233
+ // dbg!(name, fields, self.root_schema);
234
+ // todo!("Implement deserialization for struct");
235
+ let schema = self . root_schema ;
236
+ let mut this = self ;
237
+ this. deserialize_struct_with_schema ( name, fields, visitor, schema)
242
238
}
243
239
244
240
fn deserialize_enum < V > (
@@ -268,8 +264,8 @@ impl<'de, R: Read> serde::de::Deserializer<'de> for SchemaAwareReadDeserializer<
268
264
}
269
265
}
270
266
271
- impl < R : Read > SchemaAwareReadDeserializer < ' _ , R > {
272
- fn deserialize_bool_with_schema < ' de , V > (
267
+ impl < ' de , R : Read > SchemaAwareReadDeserializer < ' de , R > {
268
+ fn deserialize_bool_with_schema < V > (
273
269
& mut self ,
274
270
visitor : V ,
275
271
schema : & Schema ,
@@ -278,8 +274,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
278
274
V : Visitor < ' de > ,
279
275
{
280
276
let create_error = |cause : & str | {
281
- Details :: SerializeValueWithSchema {
282
- // TODO: DeserializeValueWithSchema
277
+ Details :: DeserializeValueWithSchema {
283
278
value_type : "bool" ,
284
279
value : format ! ( "Cause: {cause}" ) ,
285
280
schema : schema. clone ( ) ,
@@ -315,7 +310,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
315
310
}
316
311
}
317
312
318
- fn deserialize_i32_with_schema < ' de , V > (
313
+ fn deserialize_i32_with_schema < V > (
319
314
& mut self ,
320
315
visitor : V ,
321
316
schema : & Schema ,
@@ -324,8 +319,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
324
319
V : Visitor < ' de > ,
325
320
{
326
321
let create_error = |cause : & str | {
327
- Error :: new ( Details :: SerializeValueWithSchema {
328
- // TODO: DeserializeValueWithSchema
322
+ Error :: new ( Details :: DeserializeValueWithSchema {
329
323
value_type : "i32" ,
330
324
value : format ! ( "Cause: {cause}" ) ,
331
325
schema : schema. clone ( ) ,
@@ -334,7 +328,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
334
328
335
329
match schema {
336
330
Schema :: Int | Schema :: TimeMillis | Schema :: Date => {
337
- let int = zag_i32 ( & mut self . reader ) ?;
331
+ let int = zag_i32 ( self . reader ) ?;
338
332
visitor. visit_i32 ( int)
339
333
}
340
334
Schema :: Union ( union_schema) => {
@@ -356,7 +350,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
356
350
}
357
351
}
358
352
359
- fn deserialize_i64_with_schema < ' de , V > (
353
+ fn deserialize_i64_with_schema < V > (
360
354
& mut self ,
361
355
visitor : V ,
362
356
schema : & Schema ,
@@ -365,8 +359,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
365
359
V : Visitor < ' de > ,
366
360
{
367
361
let create_error = |cause : & str | {
368
- Details :: SerializeValueWithSchema {
369
- // TODO: DeserializeValueWithSchema
362
+ Details :: DeserializeValueWithSchema {
370
363
value_type : "i64" ,
371
364
value : format ! ( "Cause: {cause}" ) ,
372
365
schema : schema. clone ( ) ,
@@ -376,7 +369,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
376
369
377
370
match schema {
378
371
Schema :: Int | Schema :: TimeMillis | Schema :: Date => {
379
- let long = zag_i64 ( & mut self . reader ) ?;
372
+ let long = zag_i64 ( self . reader ) ?;
380
373
let int = i32:: try_from ( long)
381
374
. map_err ( |cause| create_error ( cause. to_string ( ) . as_str ( ) ) ) ?;
382
375
visitor. visit_i32 ( int)
@@ -389,7 +382,7 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
389
382
| Schema :: LocalTimestampMillis
390
383
| Schema :: LocalTimestampMicros
391
384
| Schema :: LocalTimestampNanos => {
392
- let long = zag_i64 ( & mut self . reader ) ?;
385
+ let long = zag_i64 ( self . reader ) ?;
393
386
visitor. visit_i64 ( long)
394
387
}
395
388
Schema :: Union ( union_schema) => {
@@ -420,6 +413,149 @@ impl<R: Read> SchemaAwareReadDeserializer<'_, R> {
420
413
) ) ) ,
421
414
}
422
415
}
416
+
417
+ fn deserialize_struct_with_schema < V > (
418
+ & ' de mut self ,
419
+ name : & ' static str ,
420
+ fields : & ' static [ & ' static str ] ,
421
+ visitor : V ,
422
+ schema : & ' de Schema ,
423
+ ) -> Result < V :: Value , Error >
424
+ where
425
+ V : Visitor < ' de > ,
426
+ {
427
+ let create_error = |cause : & str | {
428
+ Details :: DeserializeValueWithSchema {
429
+ value_type : "struct" ,
430
+ value : format ! ( "Cause: {cause}" ) ,
431
+ schema : schema. clone ( ) ,
432
+ }
433
+ . into ( )
434
+ } ;
435
+
436
+ match schema {
437
+ Schema :: Record ( record_schema) => visitor. visit_map (
438
+ RecordSchemaAwareReadDeserializer :: new ( self , name, fields. iter ( ) , record_schema) ,
439
+ ) ,
440
+ Schema :: Union ( union_schema) => {
441
+ for variant_schema in union_schema. schemas . iter ( ) {
442
+ match variant_schema {
443
+ Schema :: Int
444
+ | Schema :: TimeMillis
445
+ | Schema :: Date
446
+ | Schema :: Long
447
+ | Schema :: TimeMicros
448
+ | Schema :: TimestampMillis
449
+ | Schema :: TimestampMicros
450
+ | Schema :: TimestampNanos
451
+ | Schema :: LocalTimestampMillis
452
+ | Schema :: LocalTimestampMicros
453
+ | Schema :: LocalTimestampNanos => {
454
+ return self . deserialize_i64_with_schema ( visitor, variant_schema) ;
455
+ }
456
+ _ => { /* skip */ }
457
+ }
458
+ }
459
+ Err ( create_error ( & format ! (
460
+ "The union schema must have a Long[-like] variant: {schema:?}"
461
+ ) ) )
462
+ }
463
+ unexpected => Err ( create_error ( & format ! (
464
+ "Expected a Long[-like] schema, found: {unexpected:?}"
465
+ ) ) ) ,
466
+ }
467
+ }
468
+ }
469
+
470
+ struct RecordSchemaAwareReadDeserializer < ' s , R : Read > {
471
+ deser : & ' s mut SchemaAwareReadDeserializer < ' s , R > ,
472
+ schema_name : & ' static str ,
473
+ fields : Iter < ' s , & ' static str > ,
474
+ record_schema : & ' s crate :: schema:: RecordSchema ,
475
+ }
476
+
477
+ impl < ' s , R : Read > RecordSchemaAwareReadDeserializer < ' s , R > {
478
+ fn new (
479
+ deser : & ' s mut SchemaAwareReadDeserializer < ' s , R > ,
480
+ schema_name : & ' static str ,
481
+ fields : Iter < ' s , & ' static str > ,
482
+ record_schema : & ' s crate :: schema:: RecordSchema ,
483
+ ) -> Self {
484
+ Self {
485
+ deser,
486
+ schema_name,
487
+ fields,
488
+ record_schema,
489
+ }
490
+ }
491
+ }
492
+
493
+ impl < ' de , R : Read > de:: MapAccess < ' de > for RecordSchemaAwareReadDeserializer < ' de , R > {
494
+ type Error = Error ;
495
+
496
+ fn next_key_seed < K > ( & mut self , seed : K ) -> Result < Option < K :: Value > , Self :: Error >
497
+ where
498
+ K : de:: DeserializeSeed < ' de > ,
499
+ {
500
+ match self . fields . next ( ) {
501
+ Some ( & field_name) => seed
502
+ . deserialize ( StringDeserializer { input : field_name } )
503
+ . map ( Some ) ,
504
+ None => Ok ( None ) ,
505
+ }
506
+ }
507
+
508
+ fn next_value_seed < V > ( & mut self , seed : V ) -> Result < V :: Value , Self :: Error >
509
+ where
510
+ V : de:: DeserializeSeed < ' de > ,
511
+ {
512
+ match self . fields . next ( ) {
513
+ Some ( & field_name) => {
514
+ let field_idx = self . record_schema . lookup . get ( field_name) . ok_or_else ( || {
515
+ return Error :: new ( Details :: DeserializeValueWithSchema {
516
+ value_type : "field" ,
517
+ value : format ! ( "Field '{field_name}' not found in record schema" ) ,
518
+ schema : Schema :: Record ( self . record_schema . clone ( ) ) ,
519
+ } ) ;
520
+ } ) ?;
521
+ let record_field = self . record_schema . fields . get ( * field_idx) . ok_or_else ( || {
522
+ return Error :: new ( Details :: DeserializeValueWithSchema {
523
+ value_type : "field" ,
524
+ value : format ! ( "Field index {field_idx} out of bounds" ) ,
525
+ schema : Schema :: Record ( self . record_schema . clone ( ) ) ,
526
+ } ) ;
527
+ } ) ?;
528
+ let field_schema = & record_field. schema ;
529
+ seed. deserialize ( SchemaAwareReadDeserializer :: new (
530
+ self . deser . reader ,
531
+ field_schema,
532
+ ) )
533
+ }
534
+ None => Err ( de:: Error :: custom ( "should not happen - too many values" ) ) ,
535
+ }
536
+ }
537
+ }
538
+
539
+ #[ derive( Clone ) ]
540
+ struct StringDeserializer < ' de > {
541
+ input : & ' de str ,
542
+ }
543
+
544
+ impl < ' de > de:: Deserializer < ' de > for StringDeserializer < ' de > {
545
+ type Error = Error ;
546
+
547
+ fn deserialize_any < V > ( self , visitor : V ) -> Result < V :: Value , Self :: Error >
548
+ where
549
+ V : Visitor < ' de > ,
550
+ {
551
+ visitor. visit_str ( self . input )
552
+ }
553
+
554
+ forward_to_deserialize_any ! {
555
+ bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
556
+ seq bytes byte_buf map unit_struct newtype_struct
557
+ tuple_struct struct tuple enum identifier ignored_any
558
+ }
423
559
}
424
560
425
561
#[ cfg( test) ]
0 commit comments