Skip to content

Commit 1e486c4

Browse files
committed
0.8.5 resolved serializing unicode chars and erros around escaped
characters #53
1 parent fca6214 commit 1e486c4

File tree

4 files changed

+26
-11
lines changed

4 files changed

+26
-11
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ license = "MIT"
99

1010
[dependencies]
1111
itoa = "0.1"
12-
dtoa = "0.1"

src/codegen.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::num::FpCategory;
33
use JsonValue;
44

55
extern crate itoa;
6-
extern crate dtoa;
76

87
const QU: u8 = b'"';
98
const BS: u8 = b'\\';
@@ -59,13 +58,18 @@ pub trait Generator {
5958

6059
#[inline(never)]
6160
fn write_string_complex(&mut self, string: &str, mut start: usize) {
61+
self.write(string[ .. start].as_bytes());
62+
6263
for (index, ch) in string.bytes().enumerate().skip(start) {
6364
let escape = ESCAPED[ch as usize];
6465
if escape > 0 {
6566
self.write(string[start .. index].as_bytes());
6667
self.write(&[b'\\', escape]);
6768
start = index + 1;
6869
}
70+
if escape == b'u' {
71+
write!(self.get_writer(), "{:04x}", ch).unwrap();
72+
}
6973
}
7074
self.write(string[start ..].as_bytes());
7175

@@ -93,13 +97,12 @@ pub trait Generator {
9397
if num.fract() == 0.0 && num.abs() < 1e19 {
9498
itoa::write(self.get_writer(), num as i64).unwrap();
9599
} else {
96-
dtoa::write(self.get_writer(), num).unwrap();
97-
// let abs = num.abs();
98-
// if abs < 1e-15 || abs > 1e19 {
99-
// write!(self.get_writer(), "{:e}", num).unwrap();
100-
// } else {
101-
// write!(self.get_writer(), "{}", num).unwrap();
102-
// }
100+
let abs = num.abs();
101+
if abs < 1e-15 || abs > 1e19 {
102+
write!(self.get_writer(), "{:e}", num).unwrap();
103+
} else {
104+
write!(self.get_writer(), "{}", num).unwrap();
105+
}
103106
}
104107
},
105108
FpCategory::Zero => {
@@ -177,7 +180,9 @@ impl DumpGenerator {
177180
}
178181

179182
pub fn consume(self) -> String {
180-
String::from_utf8(self.code).unwrap()
183+
// Original strings were unicode, numbers are all ASCII,
184+
// therefore this is safe.
185+
unsafe { String::from_utf8_unchecked(self.code) }
181186
}
182187
}
183188

@@ -221,7 +226,7 @@ impl PrettyGenerator {
221226
}
222227

223228
pub fn consume(self) -> String {
224-
String::from_utf8(self.code).unwrap()
229+
unsafe { String::from_utf8_unchecked(self.code) }
225230
}
226231
}
227232

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ impl JsonValue {
235235
gen.consume()
236236
}
237237

238+
/// Dumps the JSON as byte stream into an instance of `std::io::Write`.
238239
pub fn to_writer<W: Write>(&self, writer: &mut W) {
239240
let mut gen = WriterGenerator::new(writer);
240241
gen.write_json(self);

tests/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,16 @@ mod unit {
291291
assert_eq!(stringify("foo/bar"), r#""foo/bar""#);
292292
}
293293

294+
#[test]
295+
fn stringify_escaped() {
296+
assert_eq!(stringify("http://www.google.com/\t"), r#""http://www.google.com/\t""#);
297+
}
298+
299+
#[test]
300+
fn stringify_control_escaped() {
301+
assert_eq!(stringify("foo\u{7f}bar\u{0}baz"), r#""foo\u007fbar\u0000baz""#);
302+
}
303+
294304
#[test]
295305
fn stringify_pretty_object() {
296306
let object = object!{

0 commit comments

Comments
 (0)