@@ -6,31 +6,33 @@ extern crate itoa;
66
77const QU : u8 = b'"' ;
88const BS : u8 = b'\\' ;
9- const B : u8 = b'b' ;
10- const T : u8 = b't' ;
11- const N : u8 = b'n' ;
12- const F : u8 = b'f' ;
13- const R : u8 = b'r' ;
14- const U : u8 = b'u' ;
15-
9+ const BB : u8 = b'b' ;
10+ const TT : u8 = b't' ;
11+ const NN : u8 = b'n' ;
12+ const FF : u8 = b'f' ;
13+ const RR : u8 = b'r' ;
14+ const UU : u8 = b'u' ;
15+ const __: u8 = 0 ;
16+
17+ // Look up table for characters that need escaping in a product string
1618static ESCAPED : [ u8 ; 256 ] = [
1719// 0 1 2 3 4 5 6 7 8 9 A B C D E F
18- U , U , U , U , U , U , U , U , B , T , N , U , F , R , U , U , // 0
19- U , U , U , U , U , U , U , U , U , U , U , U , U , U , U , U , // 1
20- 0 , 0 , QU , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 2
21- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 3
22- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 4
23- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BS , 0 , 0 , 0 , // 5
24- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 6
25- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , U , // 7
26- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 8
27- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 9
28- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // A
29- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // B
30- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // C
31- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // D
32- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // E
33- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // F
20+ UU , UU , UU , UU , UU , UU , UU , UU , BB , TT , NN , UU , FF , RR , UU , UU , // 0
21+ UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , UU , // 1
22+ __ , __ , QU , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 2
23+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 3
24+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 4
25+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , BS , __ , __ , __ , // 5
26+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 6
27+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 7
28+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 8
29+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // 9
30+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // A
31+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // B
32+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // C
33+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // D
34+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // E
35+ __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , __ , // F
3436] ;
3537
3638pub trait Generator {
@@ -90,6 +92,7 @@ pub trait Generator {
9092 self . write_char ( b'"' ) ;
9193 }
9294
95+ #[ inline( always) ]
9396 fn write_number ( & mut self , num : f64 ) {
9497 match num. classify ( ) {
9598 FpCategory :: Normal |
@@ -128,38 +131,50 @@ pub trait Generator {
128131 JsonValue :: Null => self . write ( b"null" ) ,
129132 JsonValue :: Array ( ref array) => {
130133 self . write_char ( b'[' ) ;
131- self . indent ( ) ;
132- let mut first = true ;
133- for item in array {
134- if first {
135- first = false ;
136- self . new_line ( ) ;
137- } else {
138- self . write_char ( b',' ) ;
139- self . new_line ( ) ;
140- }
134+ let mut iter = array. iter ( ) ;
135+
136+ if let Some ( item) = iter. next ( ) {
137+ self . indent ( ) ;
138+ self . new_line ( ) ;
141139 self . write_json ( item) ;
140+ } else {
141+ self . write_char ( b']' ) ;
142+ return ;
142143 }
144+
145+ for item in iter {
146+ self . write_char ( b',' ) ;
147+ self . new_line ( ) ;
148+ self . write_json ( item) ;
149+ }
150+
143151 self . dedent ( ) ;
144152 self . new_line ( ) ;
145153 self . write_char ( b']' ) ;
146154 } ,
147155 JsonValue :: Object ( ref object) => {
148156 self . write_char ( b'{' ) ;
149- self . indent ( ) ;
150- let mut first = true ;
151- for ( key, value) in object. iter ( ) {
152- if first {
153- first = false ;
154- self . new_line ( ) ;
155- } else {
156- self . write_char ( b',' ) ;
157- self . new_line ( ) ;
158- }
157+ let mut iter = object. iter ( ) ;
158+
159+ if let Some ( ( key, value) ) = iter. next ( ) {
160+ self . indent ( ) ;
161+ self . new_line ( ) ;
162+ self . write_string ( key) ;
163+ self . write_min ( b": " , b':' ) ;
164+ self . write_json ( value) ;
165+ } else {
166+ self . write_char ( b'}' ) ;
167+ return ;
168+ }
169+
170+ for ( key, value) in iter {
171+ self . write_char ( b',' ) ;
172+ self . new_line ( ) ;
159173 self . write_string ( key) ;
160174 self . write_min ( b": " , b':' ) ;
161175 self . write_json ( value) ;
162176 }
177+
163178 self . dedent ( ) ;
164179 self . new_line ( ) ;
165180 self . write_char ( b'}' ) ;
0 commit comments