Skip to content

Commit 7e082da

Browse files
authored
Merge pull request #47 from maciejhirsz/0.8.0
0.8.0 closes #34, fixes #36, fixes #40, fixes #41, fixes #42, fixes #44, fixes #45, fixes #46.
2 parents 4398d77 + a0f515a commit 7e082da

File tree

7 files changed

+389
-450
lines changed

7 files changed

+389
-450
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "json"
3-
version = "0.7.4"
3+
version = "0.8.0"
44
authors = ["Maciej Hirsz <[email protected]>"]
55
description = "JSON implementation in Rust"
66
repository = "https://github.com/maciejhirsz/json-rust"

src/codegen.rs

+54-54
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1+
use std::io::Write;
2+
use std::num::FpCategory;
13
use JsonValue;
24

35
pub 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

149161
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
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

187193
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);
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
}

src/error.rs

-21
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
use parser::Token;
21
use std::error::Error;
32
use std::fmt;
43
use std::char;
54

65
#[derive(Debug, PartialEq)]
76
pub enum JsonError {
8-
UnexpectedToken {
9-
token: String,
10-
line: usize,
11-
column: usize,
12-
},
137
UnexpectedCharacter {
148
ch: char,
159
line: usize,
@@ -23,14 +17,6 @@ pub enum JsonError {
2317
}
2418

2519
impl JsonError {
26-
pub fn unexpected_token(token: Token,) -> Self {
27-
JsonError::UnexpectedToken {
28-
token: token.to_string(),
29-
line: 0,
30-
column: 0,
31-
}
32-
}
33-
3420
pub fn wrong_type(expected: &str) -> Self {
3521
JsonError::WrongType(expected.into())
3622
}
@@ -45,12 +31,6 @@ impl fmt::Display for JsonError {
4531
use JsonError::*;
4632

4733
match *self {
48-
UnexpectedToken {
49-
ref token,
50-
ref line,
51-
ref column,
52-
} => write!(f, "Unexpected token: {} at ({}:{})", token, line, column),
53-
5434
UnexpectedCharacter {
5535
ref ch,
5636
ref line,
@@ -70,7 +50,6 @@ impl Error for JsonError {
7050
fn description(&self) -> &str {
7151
use JsonError::*;
7252
match *self {
73-
UnexpectedToken { .. } => "Unexpected token",
7453
UnexpectedCharacter { .. } => "Unexpected character",
7554
UnexpectedEndOfJson => "Unexpected end of JSON",
7655
FailedUtf8Parsing => "Failed to read bytes as UTF-8 from JSON",

src/lib.rs

-5
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,6 @@ pub fn from<T>(value: T) -> JsonValue where T: Into<JsonValue> {
264264
value.into()
265265
}
266266

267-
#[deprecated(since="0.5.0", note="Use `value.dump(0)` instead")]
268-
pub fn stringify_ref(root: &JsonValue) -> String {
269-
root.dump()
270-
}
271-
272267
/// Pretty prints out the value as JSON string.
273268
pub fn stringify<T>(root: T) -> String where T: Into<JsonValue> {
274269
let root: JsonValue = root.into();

0 commit comments

Comments
 (0)