@@ -464,8 +464,20 @@ impl<'a> ::Encoder for Encoder<'a> {
464
464
}
465
465
466
466
fn emit_map_elt_key( & mut self , idx: uint, f: |& mut Encoder < ' a > |) {
467
+ use std:: str:: from_utf8;
467
468
if idx != 0 { try!( write ! ( self . wr, "," ) ) }
468
- f( self )
469
+ // ref #12967, make sure to wrap a key in double quotes,
470
+ // in the event that its of a type that omits them (eg numbers)
471
+ let mut buf = MemWriter :: new( ) ;
472
+ let mut check_encoder = Encoder :: new( & mut buf) ;
473
+ f( & mut check_encoder) ;
474
+ let buf = buf. unwrap( ) ;
475
+ let out = from_utf8( buf) . unwrap( ) ;
476
+ let needs_wrapping = out. char_at( 0 ) != '"' &&
477
+ out. char_at_reverse( out. len( ) ) != '"' ;
478
+ if needs_wrapping { try!( write ! ( self . wr, "\" " ) ) ; }
479
+ f( self ) ;
480
+ if needs_wrapping { try!( write ! ( self . wr, "\" " ) ) ; }
469
481
}
470
482
471
483
fn emit_map_elt_val( & mut self , _idx: uint, f: |& mut Encoder < ' a > |) {
@@ -659,13 +671,25 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
659
671
}
660
672
661
673
fn emit_map_elt_key( & mut self , idx: uint, f: |& mut PrettyEncoder < ' a > |) {
674
+ use std:: str:: from_utf8;
662
675
if idx == 0 {
663
676
try!( write ! ( self . wr, "\n " ) ) ;
664
677
} else {
665
678
try!( write ! ( self . wr, ",\n " ) ) ;
666
679
}
667
680
try!( write ! ( self . wr, "{}" , spaces( self . indent) ) ) ;
681
+ // ref #12967, make sure to wrap a key in double quotes,
682
+ // in the event that its of a type that omits them (eg numbers)
683
+ let mut buf = MemWriter :: new( ) ;
684
+ let mut check_encoder = PrettyEncoder :: new( & mut buf) ;
685
+ f( & mut check_encoder) ;
686
+ let buf = buf. unwrap( ) ;
687
+ let out = from_utf8( buf) . unwrap( ) ;
688
+ let needs_wrapping = out. char_at( 0 ) != '"' &&
689
+ out. char_at_reverse( out. len( ) ) != '"' ;
690
+ if needs_wrapping { try!( write ! ( self . wr, "\" " ) ) ; }
668
691
f( self ) ;
692
+ if needs_wrapping { try!( write ! ( self . wr, "\" " ) ) ; }
669
693
}
670
694
671
695
fn emit_map_elt_val( & mut self , _idx: uint, f: |& mut PrettyEncoder < ' a > |) {
@@ -1306,9 +1330,15 @@ impl ::Decoder for Decoder {
1306
1330
}
1307
1331
1308
1332
fn read_f64 ( & mut self ) -> f64 {
1333
+ use std:: from_str:: FromStr ;
1309
1334
debug ! ( "read_f64" ) ;
1310
1335
match self . stack . pop ( ) . unwrap ( ) {
1311
1336
Number ( f) => f,
1337
+ String ( s) => {
1338
+ // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
1339
+ // is going to have a string here, as per JSON spec..
1340
+ FromStr :: from_str ( s) . unwrap ( )
1341
+ } ,
1312
1342
value => self . expected ( "number" , & value)
1313
1343
}
1314
1344
}
@@ -2519,4 +2549,57 @@ mod tests {
2519
2549
let expected_null = ( ) ;
2520
2550
assert!( json_null. is_some( ) && json_null. unwrap( ) == expected_null) ;
2521
2551
}
2552
+
2553
+ #[ test]
2554
+ fn test_encode_hashmap_with_numeric_key( ) {
2555
+ use std:: str :: from_utf8;
2556
+ use std:: io:: Writer ;
2557
+ use std:: io:: MemWriter ;
2558
+ use collections:: HashMap ;
2559
+ let mut hm: HashMap <uint, bool > = HashMap :: new( ) ;
2560
+ hm. insert( 1 , true ) ;
2561
+ let mut mem_buf = MemWriter :: new( ) ;
2562
+ {
2563
+ let mut encoder = Encoder :: new( & mut mem_buf as & mut io:: Writer ) ;
2564
+ hm. encode( & mut encoder)
2565
+ }
2566
+ let bytes = mem_buf. unwrap( ) ;
2567
+ let json_str = from_utf8( bytes) . unwrap( ) ;
2568
+ match from_str( json_str) {
2569
+ Err ( _) => fail!( "Unable to parse json_str: {:?}" , json_str) ,
2570
+ _ => { } // it parsed and we are good to go
2571
+ }
2572
+ }
2573
+ #[ test]
2574
+ fn test_prettyencode_hashmap_with_numeric_key( ) {
2575
+ use std:: str :: from_utf8;
2576
+ use std:: io:: Writer ;
2577
+ use std:: io:: MemWriter ;
2578
+ use collections:: HashMap ;
2579
+ let mut hm: HashMap <uint, bool > = HashMap :: new( ) ;
2580
+ hm. insert( 1 , true ) ;
2581
+ let mut mem_buf = MemWriter :: new( ) ;
2582
+ {
2583
+ let mut encoder = PrettyEncoder :: new( & mut mem_buf as & mut io:: Writer ) ;
2584
+ hm. encode( & mut encoder)
2585
+ }
2586
+ let bytes = mem_buf. unwrap( ) ;
2587
+ let json_str = from_utf8( bytes) . unwrap( ) ;
2588
+ match from_str( json_str) {
2589
+ Err ( _) => fail!( "Unable to parse json_str: {:?}" , json_str) ,
2590
+ _ => { } // it parsed and we are good to go
2591
+ }
2592
+ }
2593
+ #[ test]
2594
+ fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key( ) {
2595
+ use collections:: HashMap ;
2596
+ use Decodable ;
2597
+ let json_str = "{\" 1\" :true}" ;
2598
+ let json_obj = match from_str( json_str) {
2599
+ Err ( _) => fail!( "Unable to parse json_str: {:?}" , json_str) ,
2600
+ Ok ( o) => o
2601
+ } ;
2602
+ let mut decoder = Decoder :: new( json_obj) ;
2603
+ let hm: HashMap <uint, bool > = Decodable :: decode( & mut decoder) ;
2604
+ }
2522
2605
}
0 commit comments