@@ -420,16 +420,24 @@ fn fmt_number_or_null(v: f64) -> string::String {
420
420
}
421
421
}
422
422
423
+ #[ deriving( PartialEq ) ]
424
+ enum EmittingMapKeyState {
425
+ NotEmitting ,
426
+ Emitting ,
427
+ EmittedValidMapKey ,
428
+ }
429
+
423
430
/// A structure for implementing serialization to JSON.
424
431
pub struct Encoder < ' a > {
425
432
writer : & ' a mut ( io:: Writer +' a ) ,
433
+ emitting_map_key : EmittingMapKeyState ,
426
434
}
427
435
428
436
impl < ' a > Encoder < ' a > {
429
437
/// Creates a new JSON encoder whose output will be written to the writer
430
438
/// specified.
431
439
pub fn new ( writer : & ' a mut io:: Writer ) -> Encoder < ' a > {
432
- Encoder { writer : writer }
440
+ Encoder { writer : writer, emitting_map_key : EmittingMapKeyState :: NotEmitting , }
433
441
}
434
442
435
443
/// Encode the specified struct into a json [u8]
@@ -446,20 +454,31 @@ impl<'a> Encoder<'a> {
446
454
}
447
455
}
448
456
457
+ macro_rules! emit_enquoted_if_mapkey {
458
+ ( $enc: ident, $e: expr) => {
459
+ if $enc. emitting_map_key == EmittingMapKeyState :: Emitting {
460
+ $enc. emitting_map_key = EmittingMapKeyState :: EmittedValidMapKey ;
461
+ write!( $enc. writer, "\" {}\" " , $e)
462
+ } else {
463
+ write!( $enc. writer, "{}" , $e)
464
+ }
465
+ }
466
+ }
467
+
449
468
impl < ' a > :: Encoder < io:: IoError > for Encoder < ' a > {
450
469
fn emit_nil ( & mut self ) -> EncodeResult { write ! ( self . writer, "null" ) }
451
470
452
- fn emit_uint ( & mut self , v : uint ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
453
- fn emit_u64 ( & mut self , v : u64 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
454
- fn emit_u32 ( & mut self , v : u32 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
455
- fn emit_u16 ( & mut self , v : u16 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
456
- fn emit_u8 ( & mut self , v : u8 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
471
+ fn emit_uint ( & mut self , v : uint ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
472
+ fn emit_u64 ( & mut self , v : u64 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
473
+ fn emit_u32 ( & mut self , v : u32 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
474
+ fn emit_u16 ( & mut self , v : u16 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
475
+ fn emit_u8 ( & mut self , v : u8 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
457
476
458
- fn emit_int ( & mut self , v : int ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
459
- fn emit_i64 ( & mut self , v : i64 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
460
- fn emit_i32 ( & mut self , v : i32 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
461
- fn emit_i16 ( & mut self , v : i16 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
462
- fn emit_i8 ( & mut self , v : i8 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
477
+ fn emit_int ( & mut self , v : int ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
478
+ fn emit_i64 ( & mut self , v : i64 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
479
+ fn emit_i32 ( & mut self , v : i32 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
480
+ fn emit_i16 ( & mut self , v : i16 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
481
+ fn emit_i8 ( & mut self , v : i8 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
463
482
464
483
fn emit_bool ( & mut self , v : bool ) -> EncodeResult {
465
484
if v {
@@ -470,16 +489,18 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
470
489
}
471
490
472
491
fn emit_f64 ( & mut self , v : f64 ) -> EncodeResult {
473
- write ! ( self . writer , "{}" , fmt_number_or_null( v) )
492
+ emit_enquoted_if_mapkey ! ( self , fmt_number_or_null( v) )
474
493
}
475
494
fn emit_f32 ( & mut self , v : f32 ) -> EncodeResult {
476
495
self . emit_f64 ( v as f64 )
477
496
}
478
497
479
498
fn emit_char ( & mut self , v : char ) -> EncodeResult {
499
+ self . emitting_map_key = EmittingMapKeyState :: EmittedValidMapKey ;
480
500
escape_char ( self . writer , v)
481
501
}
482
502
fn emit_str ( & mut self , v : & str ) -> EncodeResult {
503
+ self . emitting_map_key = EmittingMapKeyState :: EmittedValidMapKey ;
483
504
escape_str ( self . writer , v)
484
505
}
485
506
@@ -618,19 +639,13 @@ impl<'a> ::Encoder<io::IoError> for Encoder<'a> {
618
639
F : FnMut ( & mut Encoder < ' a > ) -> EncodeResult ,
619
640
{
620
641
if idx != 0 { try!( write ! ( self . writer, "," ) ) }
621
- // ref #12967, make sure to wrap a key in double quotes,
622
- // in the event that its of a type that omits them (eg numbers)
623
- let mut buf = Vec :: new ( ) ;
624
- // FIXME(14302) remove the transmute and unsafe block.
625
- unsafe {
626
- let mut check_encoder = Encoder :: new ( & mut buf) ;
627
- try!( f ( transmute ( & mut check_encoder) ) ) ;
628
- }
629
- let out = str:: from_utf8 ( buf[ ] ) . unwrap ( ) ;
630
- let needs_wrapping = out. char_at ( 0 ) != '"' && out. char_at_reverse ( out. len ( ) ) != '"' ;
631
- if needs_wrapping { try!( write ! ( self . writer, "\" " ) ) ; }
642
+ self . emitting_map_key = EmittingMapKeyState :: Emitting ;
632
643
try!( f ( self ) ) ;
633
- if needs_wrapping { try!( write ! ( self . writer, "\" " ) ) ; }
644
+ if self . emitting_map_key == EmittingMapKeyState :: EmittedValidMapKey {
645
+ self . emitting_map_key = EmittingMapKeyState :: NotEmitting ;
646
+ } else {
647
+ panic ! ( "did not emit a valid map key, aborting encoding" ) ;
648
+ }
634
649
Ok ( ( ) )
635
650
}
636
651
@@ -648,12 +663,18 @@ pub struct PrettyEncoder<'a> {
648
663
writer : & ' a mut ( io:: Writer +' a ) ,
649
664
curr_indent : uint ,
650
665
indent : uint ,
666
+ emitting_map_key : EmittingMapKeyState ,
651
667
}
652
668
653
669
impl < ' a > PrettyEncoder < ' a > {
654
670
/// Creates a new encoder whose output will be written to the specified writer
655
671
pub fn new ( writer : & ' a mut io:: Writer ) -> PrettyEncoder < ' a > {
656
- PrettyEncoder { writer : writer, curr_indent : 0 , indent : 2 , }
672
+ PrettyEncoder {
673
+ writer : writer,
674
+ curr_indent : 0 ,
675
+ indent : 2 ,
676
+ emitting_map_key : EmittingMapKeyState :: NotEmitting ,
677
+ }
657
678
}
658
679
659
680
/// Set the number of spaces to indent for each level.
@@ -669,17 +690,17 @@ impl<'a> PrettyEncoder<'a> {
669
690
impl < ' a > :: Encoder < io:: IoError > for PrettyEncoder < ' a > {
670
691
fn emit_nil ( & mut self ) -> EncodeResult { write ! ( self . writer, "null" ) }
671
692
672
- fn emit_uint ( & mut self , v : uint ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
673
- fn emit_u64 ( & mut self , v : u64 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
674
- fn emit_u32 ( & mut self , v : u32 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
675
- fn emit_u16 ( & mut self , v : u16 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
676
- fn emit_u8 ( & mut self , v : u8 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
693
+ fn emit_uint ( & mut self , v : uint ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
694
+ fn emit_u64 ( & mut self , v : u64 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
695
+ fn emit_u32 ( & mut self , v : u32 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
696
+ fn emit_u16 ( & mut self , v : u16 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
697
+ fn emit_u8 ( & mut self , v : u8 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
677
698
678
- fn emit_int ( & mut self , v : int ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
679
- fn emit_i64 ( & mut self , v : i64 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
680
- fn emit_i32 ( & mut self , v : i32 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
681
- fn emit_i16 ( & mut self , v : i16 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
682
- fn emit_i8 ( & mut self , v : i8 ) -> EncodeResult { write ! ( self . writer , "{}" , v) }
699
+ fn emit_int ( & mut self , v : int ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
700
+ fn emit_i64 ( & mut self , v : i64 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
701
+ fn emit_i32 ( & mut self , v : i32 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
702
+ fn emit_i16 ( & mut self , v : i16 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
703
+ fn emit_i8 ( & mut self , v : i8 ) -> EncodeResult { emit_enquoted_if_mapkey ! ( self , v) }
683
704
684
705
fn emit_bool ( & mut self , v : bool ) -> EncodeResult {
685
706
if v {
@@ -690,16 +711,18 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
690
711
}
691
712
692
713
fn emit_f64 ( & mut self , v : f64 ) -> EncodeResult {
693
- write ! ( self . writer , "{}" , fmt_number_or_null( v) )
714
+ emit_enquoted_if_mapkey ! ( self , fmt_number_or_null( v) )
694
715
}
695
716
fn emit_f32 ( & mut self , v : f32 ) -> EncodeResult {
696
717
self . emit_f64 ( v as f64 )
697
718
}
698
719
699
720
fn emit_char ( & mut self , v : char ) -> EncodeResult {
721
+ self . emitting_map_key = EmittingMapKeyState :: EmittedValidMapKey ;
700
722
escape_char ( self . writer , v)
701
723
}
702
724
fn emit_str ( & mut self , v : & str ) -> EncodeResult {
725
+ self . emitting_map_key = EmittingMapKeyState :: EmittedValidMapKey ;
703
726
escape_str ( self . writer , v)
704
727
}
705
728
@@ -887,19 +910,13 @@ impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> {
887
910
try!( write ! ( self . writer, ",\n " ) ) ;
888
911
}
889
912
try!( spaces ( self . writer , self . curr_indent ) ) ;
890
- // ref #12967, make sure to wrap a key in double quotes,
891
- // in the event that its of a type that omits them (eg numbers)
892
- let mut buf = Vec :: new ( ) ;
893
- // FIXME(14302) remove the transmute and unsafe block.
894
- unsafe {
895
- let mut check_encoder = PrettyEncoder :: new ( & mut buf) ;
896
- try!( f ( transmute ( & mut check_encoder) ) ) ;
897
- }
898
- let out = str:: from_utf8 ( buf[ ] ) . unwrap ( ) ;
899
- let needs_wrapping = out. char_at ( 0 ) != '"' && out. char_at_reverse ( out. len ( ) ) != '"' ;
900
- if needs_wrapping { try!( write ! ( self . writer, "\" " ) ) ; }
913
+ self . emitting_map_key = EmittingMapKeyState :: Emitting ;
901
914
try!( f ( self ) ) ;
902
- if needs_wrapping { try!( write ! ( self . writer, "\" " ) ) ; }
915
+ if self . emitting_map_key == EmittingMapKeyState :: EmittedValidMapKey {
916
+ self . emitting_map_key = EmittingMapKeyState :: NotEmitting ;
917
+ } else {
918
+ panic ! ( "did not emit a valid map key, aborting encoding" ) ;
919
+ }
903
920
Ok ( ( ) )
904
921
}
905
922
0 commit comments