1+ use std:: io:: Write ;
2+ use std:: num:: FpCategory ;
13use JsonValue ;
24
35pub trait Generator {
4- fn current_index ( & self ) -> usize ;
6+ fn get_buffer ( & mut self ) -> & mut Vec < u8 > ;
57
6- fn new_line ( & mut self ) { }
8+ fn current_index ( & mut self ) -> usize {
9+ self . get_buffer ( ) . len ( )
10+ }
11+
12+ #[ inline( always) ]
13+ fn write ( & mut self , slice : & [ u8 ] ) {
14+ self . get_buffer ( ) . extend_from_slice ( slice)
15+ }
716
8- fn write ( & mut self , slice : & [ u8 ] ) ;
17+ #[ inline( always) ]
18+ fn write_char ( & mut self , ch : u8 ) {
19+ self . get_buffer ( ) . push ( ch)
20+ }
921
1022 fn write_min ( & mut self , slice : & [ u8 ] , minslice : & [ u8 ] ) ;
1123
12- fn write_char ( & mut self , ch : u8 ) ;
24+ fn new_line ( & mut self ) { }
1325
1426 fn indent ( & mut self ) { }
1527
@@ -46,41 +58,41 @@ pub trait Generator {
4658 }
4759
4860 fn write_number ( & mut self , mut num : f64 ) {
49- if num < 0.0 {
50- num = -num;
51- self . write_char ( b'-' ) ;
61+ match num. classify ( ) {
62+ FpCategory :: Nan |
63+ FpCategory :: Infinite => {
64+ self . write ( b"null" ) ;
65+ return ;
66+ } ,
67+ FpCategory :: Zero => {
68+ self . write ( if num. is_sign_negative ( ) { b"-0" } else { b"0" } ) ;
69+ return ;
70+ } ,
71+ _ => { } ,
5272 }
5373
54- if num > 1e19 || num < 1e-15 {
55- self . write ( format ! ( "{:e}" , num) . as_bytes ( ) ) ;
56- return ;
74+ if num. is_sign_negative ( ) {
75+ num = num. abs ( ) ;
76+ self . write_char ( b'-' ) ;
5777 }
5878
59- let start = self . current_index ( ) ;
60-
61- self . write_digits_from_u64 ( num as u64 ) ;
62-
63- let mut fract = num. fract ( ) ;
79+ let fract = num. fract ( ) ;
6480
65- if fract < 1e-16 {
81+ if fract > 0.0 {
82+ if num < 1e-15 {
83+ write ! ( self . get_buffer( ) , "{:e}" , num) . unwrap ( ) ;
84+ } else {
85+ write ! ( self . get_buffer( ) , "{}" , num) . unwrap ( ) ;
86+ }
6687 return ;
6788 }
6889
69- let mut length = self . current_index ( ) - start;
70-
71- fract *= 10.0 ;
72-
73- self . write_char ( b'.' ) ;
74- self . write_char ( ( fract as u8 ) + b'0' ) ;
75- fract = fract. fract ( ) ;
76- length += 2 ;
77-
78- while length < 17 && fract > 1e-15 {
79- fract *= 10.0 ;
80- self . write_char ( ( fract as u8 ) + b'0' ) ;
81- fract = fract. fract ( ) ;
82- length += 1 ;
90+ if num > 1e19 || num < 1e-15 {
91+ write ! ( self . get_buffer( ) , "{:e}" , num) . unwrap ( ) ;
92+ return ;
8393 }
94+
95+ self . write_digits_from_u64 ( num as u64 ) ;
8496 }
8597
8698 fn write_json ( & mut self , json : & JsonValue ) {
@@ -147,22 +159,16 @@ impl DumpGenerator {
147159}
148160
149161impl Generator for DumpGenerator {
150- fn current_index ( & self ) -> usize {
151- self . code . len ( )
152- }
153-
154- fn write ( & mut self , slice : & [ u8 ] ) {
155- self . code . extend_from_slice ( slice) ;
162+ #[ inline( always) ]
163+ fn get_buffer ( & mut self ) -> & mut Vec < u8 > {
164+ & mut self . code
156165 }
157166
167+ #[ inline( always) ]
158168 fn write_min ( & mut self , _: & [ u8 ] , minslice : & [ u8 ] ) {
159169 self . code . extend_from_slice ( minslice) ;
160170 }
161171
162- fn write_char ( & mut self , ch : u8 ) {
163- self . code . push ( ch) ;
164- }
165-
166172 fn consume ( self ) -> String {
167173 String :: from_utf8 ( self . code ) . unwrap ( )
168174 }
@@ -185,8 +191,14 @@ impl PrettyGenerator {
185191}
186192
187193impl Generator for PrettyGenerator {
188- fn current_index ( & self ) -> usize {
189- self . code . len ( )
194+ #[ inline( always) ]
195+ fn get_buffer ( & mut self ) -> & mut Vec < u8 > {
196+ & mut self . code
197+ }
198+
199+ #[ inline( always) ]
200+ fn write_min ( & mut self , slice : & [ u8 ] , _: & [ u8 ] ) {
201+ self . code . extend_from_slice ( slice) ;
190202 }
191203
192204 fn new_line ( & mut self ) {
@@ -196,18 +208,6 @@ impl Generator for PrettyGenerator {
196208 }
197209 }
198210
199- fn write ( & mut self , slice : & [ u8 ] ) {
200- self . code . extend_from_slice ( slice) ;
201- }
202-
203- fn write_min ( & mut self , slice : & [ u8 ] , _: & [ u8 ] ) {
204- self . code . extend_from_slice ( slice) ;
205- }
206-
207- fn write_char ( & mut self , ch : u8 ) {
208- self . code . push ( ch) ;
209- }
210-
211211 fn indent ( & mut self ) {
212212 self . dent += 1 ;
213213 }
0 commit comments