@@ -7,34 +7,42 @@ companion module with the same name as the item.
7
7
8
8
For example, a type like:
9
9
10
- type node_id = uint;
10
+ #[auto_serialize2]
11
+ struct Node {id: uint}
11
12
12
13
would generate two implementations like:
13
14
14
- impl node_id : Serializable {
15
+ impl Node : Serializable {
15
16
fn serialize<S: Serializer>(s: &S) {
16
- s.emit_uint(self)
17
+ do s.emit_struct("Node") {
18
+ s.emit_field("id", 0, || s.emit_uint(self))
19
+ }
17
20
}
18
21
}
19
22
20
23
impl node_id: Deserializable {
21
- static fn deserialize<D: Deserializer>(d: &D) -> node_id {
22
- d.read_uint()
24
+ static fn deserialize<D: Deserializer>(d: &D) -> Node {
25
+ do d.read_struct("Node") {
26
+ Node {
27
+ id: d.read_field(~"x", 0, || deserialize(d))
28
+ }
29
+ }
23
30
}
24
31
}
25
32
26
33
Other interesting scenarios are whe the item has type parameters or
27
34
references other non-built-in types. A type definition like:
28
35
36
+ #[auto_serialize2]
29
37
type spanned<T> = {node: T, span: span};
30
38
31
39
would yield functions like:
32
40
33
41
impl<T: Serializable> spanned<T>: Serializable {
34
42
fn serialize<S: Serializer>(s: &S) {
35
43
do s.emit_rec {
36
- s.emit_field("node", 0, self.node.serialize(s));
37
- s.emit_field("span", 1, self.span.serialize(s));
44
+ s.emit_field("node", 0, || self.node.serialize(s));
45
+ s.emit_field("span", 1, || self.span.serialize(s));
38
46
}
39
47
}
40
48
}
@@ -395,33 +403,38 @@ fn mk_rec_impl(
395
403
fields : ~[ ast:: ty_field ] ,
396
404
tps : ~[ ast:: ty_param ]
397
405
) -> ~[ @ast:: item ] {
398
- // Records and structs don't have the same fields types, but they share
399
- // enough that if we extract the right subfields out we can share the
400
- // serialization generator code.
401
- let fields = do fields. map |field| {
402
- {
403
- span: field. span ,
404
- ident: field. node . ident ,
405
- mutbl: field. node . mt . mutbl ,
406
- }
407
- } ;
406
+ let fields = mk_rec_fields ( fields) ;
407
+ let ser_fields = mk_ser_fields ( cx, span, fields) ;
408
+ let deser_fields = mk_deser_fields ( cx, span, fields) ;
408
409
409
- let ser_body = mk_ser_fields ( cx, span, fields) ;
410
-
411
- // ast for `__s.emit_rec($(ser_body))`
410
+ // ast for `__s.emit_rec(|| $(ser_fields))`
412
411
let ser_body = cx. expr_call (
413
412
span,
414
413
cx. expr_field (
415
414
span,
416
415
cx. expr_var ( span, ~"__s") ,
417
416
cx. ident_of ( ~"emit_rec")
418
417
) ,
419
- ~[ ser_body ]
418
+ ~[ cx . lambda_stmts ( span , ser_fields ) ]
420
419
) ;
421
420
422
- let deser_body = do mk_deser_fields ( cx, span, fields) |fields| {
423
- cx. expr ( span, ast:: expr_rec ( fields, None ) )
424
- } ;
421
+ // ast for `read_rec(|| $(deser_fields))`
422
+ let deser_body = cx. expr_call (
423
+ span,
424
+ cx. expr_field (
425
+ span,
426
+ cx. expr_var ( span, ~"__d") ,
427
+ cx. ident_of ( ~"read_rec")
428
+ ) ,
429
+ ~[
430
+ cx. lambda_expr (
431
+ cx. expr (
432
+ span,
433
+ ast:: expr_rec ( deser_fields, None )
434
+ )
435
+ )
436
+ ]
437
+ ) ;
425
438
426
439
~[
427
440
mk_ser_impl ( cx, span, ident, tps, ser_body) ,
@@ -436,55 +449,94 @@ fn mk_struct_impl(
436
449
fields : ~[ @ast:: struct_field ] ,
437
450
tps : ~[ ast:: ty_param ]
438
451
) -> ~[ @ast:: item ] {
439
- // Records and structs don't have the same fields types, but they share
440
- // enough that if we extract the right subfields out we can share the
441
- // serialization generator code.
442
- let fields = do fields. map |field| {
443
- let ( ident, mutbl) = match field. node . kind {
444
- ast:: named_field( ident, mutbl, _) => ( ident, mutbl) ,
445
- _ => fail ~"[ auto_serialize2] does not support \
446
- unnamed fields",
447
- } ;
448
-
449
- {
450
- span: field. span ,
451
- ident: ident,
452
- mutbl: match mutbl {
453
- ast:: class_mutable => ast:: m_mutbl,
454
- ast:: class_immutable => ast:: m_imm,
455
- } ,
456
- }
457
- } ;
452
+ let fields = mk_struct_fields ( fields) ;
453
+ let ser_fields = mk_ser_fields ( cx, span, fields) ;
454
+ let deser_fields = mk_deser_fields ( cx, span, fields) ;
458
455
459
- let ser_body = mk_ser_fields ( cx, span, fields) ;
460
-
461
- // ast for `__s.emit_struct($(name), $(ser_body))`
456
+ // ast for `__s.emit_struct($(name), || $(ser_fields))`
462
457
let ser_body = cx. expr_call (
463
458
span,
464
459
cx. expr_field (
465
460
span,
466
461
cx. expr_var ( span, ~"__s") ,
467
462
cx. ident_of ( ~"emit_struct")
468
463
) ,
469
- ~[ cx. lit_str ( span, @cx. str_of ( ident) ) , ser_body]
464
+ ~[
465
+ cx. lit_str ( span, @cx. str_of ( ident) ) ,
466
+ cx. lambda_stmts ( span, ser_fields) ,
467
+ ]
470
468
) ;
471
469
472
- let deser_body = do mk_deser_fields ( cx, span, fields) |fields| {
473
- cx. expr ( span, ast:: expr_struct ( cx. path ( span, ~[ ident] ) , fields, None ) )
474
- } ;
470
+ // ast for `read_struct($(name), || $(deser_fields))`
471
+ let deser_body = cx. expr_call (
472
+ span,
473
+ cx. expr_field (
474
+ span,
475
+ cx. expr_var ( span, ~"__d") ,
476
+ cx. ident_of ( ~"read_struct")
477
+ ) ,
478
+ ~[
479
+ cx. lit_str ( span, @cx. str_of ( ident) ) ,
480
+ cx. lambda_expr (
481
+ span,
482
+ cx. expr (
483
+ span,
484
+ ast:: expr_struct (
485
+ cx. path ( span, ~[ ident] ) ,
486
+ deser_fields
487
+ None
488
+ )
489
+ )
490
+ ) ,
491
+ ]
492
+ )
475
493
476
494
~[
477
495
mk_ser_impl ( cx, span, ident, tps, ser_body) ,
478
496
mk_deser_impl ( cx, span, ident, tps, deser_body) ,
479
497
]
480
498
}
481
499
500
+ // Records and structs don't have the same fields types, but they share enough
501
+ // that if we extract the right subfields out we can share the serialization
502
+ // generator code.
503
+ type field = { span : span , ident: ast:: ident , mutbl : ast:: mutability } ;
504
+
505
+ fn mk_rec_fields ( fields : ~[ ast:: ty_field ] ) -> ~[ field ] {
506
+ do fields. map |field| {
507
+ {
508
+ span: field. span ,
509
+ ident: field. node . ident ,
510
+ mutbl: field. node . mt . mutbl ,
511
+ }
512
+ }
513
+ }
514
+
515
+ fn mk_struct_fields ( fields : ~[ @ast:: struct_field ] ) -> ~[ field ] {
516
+ do fields. map |field| {
517
+ let ( ident, mutbl) = match field. node . kind {
518
+ ast:: named_field( ident, mutbl, _) => ( ident, mutbl) ,
519
+ _ => fail ~"[ auto_serialize2] does not support \
520
+ unnamed fields",
521
+ } ;
522
+
523
+ {
524
+ span: field. span ,
525
+ ident: ident,
526
+ mutbl: match mutbl {
527
+ ast:: class_mutable => ast:: m_mutbl,
528
+ ast:: class_immutable => ast:: m_imm,
529
+ } ,
530
+ }
531
+ }
532
+ }
533
+
482
534
fn mk_ser_fields (
483
535
cx : ext_ctxt ,
484
536
span : span ,
485
- fields : ~[ { span : span , ident : ast :: ident , mutbl : ast :: mutability } ]
486
- ) -> @ast:: expr {
487
- let stmts = do fields. mapi |idx, field| {
537
+ fields : ~[ field ]
538
+ ) -> ~ [ @ast:: stmt ] {
539
+ do fields. mapi |idx, field| {
488
540
// ast for `|| self.$(name).serialize(__s)`
489
541
let expr_lambda = cx. lambda_expr (
490
542
cx. expr_call (
@@ -518,10 +570,7 @@ fn mk_ser_fields(
518
570
]
519
571
)
520
572
)
521
- } ;
522
-
523
- // ast for `|| $(stmts)`
524
- cx. lambda_stmts ( span, stmts)
573
+ }
525
574
}
526
575
527
576
fn mk_deser_fields (
0 commit comments