1
+ use std:: io:: Write ;
2
+ use std:: num:: FpCategory ;
1
3
use JsonValue ;
2
4
3
5
pub trait Generator {
4
- fn current_index ( & self ) -> usize ;
6
+ fn get_buffer ( & mut self ) -> & mut Vec < u8 > ;
5
7
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
+ }
7
16
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
+ }
9
21
10
22
fn write_min ( & mut self , slice : & [ u8 ] , minslice : & [ u8 ] ) ;
11
23
12
- fn write_char ( & mut self , ch : u8 ) ;
24
+ fn new_line ( & mut self ) { }
13
25
14
26
fn indent ( & mut self ) { }
15
27
@@ -46,41 +58,41 @@ pub trait Generator {
46
58
}
47
59
48
60
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
+ _ => { } ,
52
72
}
53
73
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'-' ) ;
57
77
}
58
78
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 ( ) ;
64
80
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
+ }
66
87
return ;
67
88
}
68
89
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 ;
83
93
}
94
+
95
+ self . write_digits_from_u64 ( num as u64 ) ;
84
96
}
85
97
86
98
fn write_json ( & mut self , json : & JsonValue ) {
@@ -147,22 +159,16 @@ impl DumpGenerator {
147
159
}
148
160
149
161
impl 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
156
165
}
157
166
167
+ #[ inline( always) ]
158
168
fn write_min ( & mut self , _: & [ u8 ] , minslice : & [ u8 ] ) {
159
169
self . code . extend_from_slice ( minslice) ;
160
170
}
161
171
162
- fn write_char ( & mut self , ch : u8 ) {
163
- self . code . push ( ch) ;
164
- }
165
-
166
172
fn consume ( self ) -> String {
167
173
String :: from_utf8 ( self . code ) . unwrap ( )
168
174
}
@@ -185,8 +191,14 @@ impl PrettyGenerator {
185
191
}
186
192
187
193
impl 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) ;
190
202
}
191
203
192
204
fn new_line ( & mut self ) {
@@ -196,18 +208,6 @@ impl Generator for PrettyGenerator {
196
208
}
197
209
}
198
210
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
-
211
211
fn indent ( & mut self ) {
212
212
self . dent += 1 ;
213
213
}
0 commit comments