@@ -464,8 +464,20 @@ impl<'a> ::Encoder for Encoder<'a> {
464464 }
465465
466466 fn emit_map_elt_key( & mut self , idx: uint, f: |& mut Encoder < ' a > |) {
467+ use std:: str:: from_utf8;
467468 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, "\" " ) ) ; }
469481 }
470482
471483 fn emit_map_elt_val( & mut self , _idx: uint, f: |& mut Encoder < ' a > |) {
@@ -659,13 +671,25 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
659671 }
660672
661673 fn emit_map_elt_key( & mut self , idx: uint, f: |& mut PrettyEncoder < ' a > |) {
674+ use std:: str:: from_utf8;
662675 if idx == 0 {
663676 try!( write ! ( self . wr, "\n " ) ) ;
664677 } else {
665678 try!( write ! ( self . wr, ",\n " ) ) ;
666679 }
667680 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, "\" " ) ) ; }
668691 f( self ) ;
692+ if needs_wrapping { try!( write ! ( self . wr, "\" " ) ) ; }
669693 }
670694
671695 fn emit_map_elt_val( & mut self , _idx: uint, f: |& mut PrettyEncoder < ' a > |) {
@@ -1306,9 +1330,15 @@ impl ::Decoder for Decoder {
13061330 }
13071331
13081332 fn read_f64 ( & mut self ) -> f64 {
1333+ use std:: from_str:: FromStr ;
13091334 debug ! ( "read_f64" ) ;
13101335 match self . stack . pop ( ) . unwrap ( ) {
13111336 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+ } ,
13121342 value => self . expected ( "number" , & value)
13131343 }
13141344 }
@@ -2519,4 +2549,57 @@ mod tests {
25192549 let expected_null = ( ) ;
25202550 assert!( json_null. is_some( ) && json_null. unwrap( ) == expected_null) ;
25212551 }
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+ }
25222605}
0 commit comments