Skip to content

Commit 0fb3777

Browse files
authored
Merge pull request #26 from maciejhirsz/0.7.2
0.7.2 fixes #25, relevant to #24
2 parents 604effa + 4b79c5f commit 0fb3777

File tree

7 files changed

+248
-139
lines changed

7 files changed

+248
-139
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.1"
3+
version = "0.7.2"
44
authors = ["Maciej Hirsz <[email protected]>"]
55
description = "JSON implementation in Rust"
66
repository = "https://github.com/maciejhirsz/json-rust"

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
Parse and serialize [JSON](http://json.org/) with ease.
1010

11-
**[Complete Documentation](http://terhix.com/doc/json/) - [Cargo](https://crates.io/crates/json) - [Repository](https://github.com/maciejhirsz/json-rust)**
11+
**[Complete Documentation](http://terhix.com/doc/json/) -**
12+
**[Cargo](https://crates.io/crates/json) -**
13+
**[Repository](https://github.com/maciejhirsz/json-rust)**
1214

1315
## Why?
1416

src/codegen.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub trait Generator {
3636

3737
fn write_digits_from_u64(&mut self, mut num: u64, length: &mut u8) {
3838
let digit = (num % 10) as u8;
39-
num /= 10;
40-
if num > 0 {
39+
if num > 9 {
40+
num /= 10;
4141
self.write_digits_from_u64(num, length);
4242
}
4343
*length += 1;
@@ -54,7 +54,7 @@ pub trait Generator {
5454
self.write_digits_from_u64(num as u64, &mut length);
5555

5656
let mut fract = num.fract();
57-
if fract < 1e-10 {
57+
if fract < 1e-16 {
5858
return;
5959
}
6060

@@ -64,7 +64,7 @@ pub trait Generator {
6464
fract = fract.fract();
6565
length += 2;
6666

67-
while length < 17 && fract > 0.01 {
67+
while length < 17 && fract > 1e-15 {
6868
fract *= 10.0;
6969
self.write_char((fract as u8) + b'0');
7070
fract = fract.fract();

src/lib.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
//!
55
//! Parse and serialize [JSON](http://json.org/) with ease.
66
//!
7-
//! **[Complete Documentation](http://terhix.com/doc/json/) - [Cargo](https://crates.io/crates/json) - [Repository](https://github.com/maciejhirsz/json-rust)**
7+
//! **[Complete Documentation](http://terhix.com/doc/json/) -**
8+
//! **[Cargo](https://crates.io/crates/json) -**
9+
//! **[Repository](https://github.com/maciejhirsz/json-rust)**
810
//!
911
//! ## Why?
1012
//!
@@ -244,6 +246,11 @@ impl fmt::Display for JsonValue {
244246
}
245247
}
246248

249+
/// Convenience for `JsonValue::from(value)`
250+
pub fn from<T>(value: T) -> JsonValue where T: Into<JsonValue> {
251+
value.into()
252+
}
253+
247254
#[deprecated(since="0.5.0", note="Use `value.dump(0)` instead")]
248255
pub fn stringify_ref(root: &JsonValue) -> String {
249256
root.dump()
@@ -262,6 +269,7 @@ pub fn stringify_pretty<T>(root: T, spaces: u16) -> String where T: Into<JsonVal
262269
root.pretty(spaces)
263270
}
264271

272+
265273
#[macro_export]
266274
macro_rules! array {
267275
[] => ($crate::JsonValue::new_array());
@@ -307,18 +315,20 @@ macro_rules! implement_extras {
307315

308316
impl From<Vec<$from>> for JsonValue {
309317
fn from(mut val: Vec<$from>) -> JsonValue {
310-
JsonValue::Array(val.drain(..)
311-
.map(|value| value.into())
312-
.collect::<Vec<JsonValue>>()
318+
JsonValue::Array(
319+
val.drain(..)
320+
.map(|value| value.into())
321+
.collect()
313322
)
314323
}
315324
}
316325

317326
impl From<Vec<Option<$from>>> for JsonValue {
318327
fn from(mut val: Vec<Option<$from>>) -> JsonValue {
319-
JsonValue::Array(val.drain(..)
320-
.map(|item| item.into())
321-
.collect::<Vec<JsonValue>>()
328+
JsonValue::Array(
329+
val.drain(..)
330+
.map(|item| item.into())
331+
.collect()
322332
)
323333
}
324334
}

src/parser.rs

+20-23
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ pub enum Token {
1919
}
2020

2121
macro_rules! expect_char {
22-
($tok:ident, $ch:pat) => {
23-
match $tok.source.next() {
24-
Some($ch) => {},
25-
Some(ch) => return Err(JsonError::unexpected_character(ch)),
26-
None => return Err(JsonError::UnexpectedEndOfJson)
27-
}
22+
($tok:ident, $( $ch:pat ),*) => {
23+
$(
24+
match $tok.source.next() {
25+
Some($ch) => {},
26+
Some(ch) => return Err(JsonError::unexpected_character(ch)),
27+
None => return Err(JsonError::UnexpectedEndOfJson)
28+
}
29+
)*
2830
}
2931
}
3032

@@ -205,22 +207,15 @@ impl<'a> Tokenizer<'a> {
205207
b'"' => Token::String(try!(self.read_string())),
206208
b'0' ... b'9' | b'-' => Token::Number(try!(self.read_number(ch))),
207209
b't' => {
208-
expect_char!(self, b'r');
209-
expect_char!(self, b'u');
210-
expect_char!(self, b'e');
210+
expect_char!(self, b'r', b'u', b'e');
211211
Token::Boolean(true)
212212
},
213213
b'f' => {
214-
expect_char!(self, b'a');
215-
expect_char!(self, b'l');
216-
expect_char!(self, b's');
217-
expect_char!(self, b'e');
214+
expect_char!(self, b'a', b'l', b's', b'e');
218215
Token::Boolean(false)
219216
},
220217
b'n' => {
221-
expect_char!(self, b'u');
222-
expect_char!(self, b'l');
223-
expect_char!(self, b'l');
218+
expect_char!(self, b'u', b'l', b'l');
224219
Token::Null
225220
},
226221
// whitespace
@@ -326,13 +321,15 @@ impl<'a> Parser<'a> {
326321

327322
fn value_from(&mut self, token: Token) -> JsonResult<JsonValue> {
328323
Ok(match token {
329-
Token::String(value) => JsonValue::String(value),
330-
Token::Number(value) => JsonValue::Number(value),
331-
Token::Boolean(value) => JsonValue::Boolean(value),
332-
Token::Null => JsonValue::Null,
333-
Token::BracketOn => return self.array(),
334-
Token::BraceOn => return self.object(),
335-
token => return Err(JsonError::unexpected_token(token))
324+
Token::String(value) => JsonValue::String(value),
325+
Token::Number(value) => JsonValue::Number(value),
326+
Token::Boolean(value) => JsonValue::Boolean(value),
327+
Token::Null => JsonValue::Null,
328+
Token::BracketOn => return self.array(),
329+
Token::BraceOn => return self.object(),
330+
token => {
331+
return Err(JsonError::unexpected_token(token))
332+
}
336333
})
337334
}
338335

src/value.rs

+93-42
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,60 @@ impl JsonValue {
6262
}
6363
}
6464

65-
/// Deprecated because the return type is planned to change to
66-
/// `Option<String>` eventually down the road.
65+
pub fn is_number(&self) -> bool {
66+
match *self {
67+
JsonValue::Number(_) => true,
68+
_ => false,
69+
}
70+
}
71+
72+
pub fn is_boolean(&self) -> bool {
73+
match *self {
74+
JsonValue::Boolean(_) => true,
75+
_ => false
76+
}
77+
}
78+
79+
pub fn is_null(&self) -> bool {
80+
match *self {
81+
JsonValue::Null => true,
82+
_ => false,
83+
}
84+
}
85+
86+
pub fn is_object(&self) -> bool {
87+
match *self {
88+
JsonValue::Object(_) => true,
89+
_ => false,
90+
}
91+
}
92+
93+
pub fn is_array(&self) -> bool {
94+
match *self {
95+
JsonValue::Array(_) => true,
96+
_ => false,
97+
}
98+
}
99+
100+
/// Checks whether the value is empty. Returns true for:
101+
///
102+
/// - empty string (`""`)
103+
/// - number `0`
104+
/// - boolean `false`
105+
/// - null
106+
/// - empty array (`array![]`)
107+
/// - empty object (`object!{}`)
108+
pub fn is_empty(&self) -> bool {
109+
match *self {
110+
JsonValue::String(ref value) => value.is_empty(),
111+
JsonValue::Number(ref value) => !value.is_normal(),
112+
JsonValue::Boolean(ref value) => !value,
113+
JsonValue::Null => true,
114+
JsonValue::Array(ref value) => value.is_empty(),
115+
JsonValue::Object(ref value) => value.is_empty(),
116+
}
117+
}
118+
67119
#[deprecated(since="0.6.1", note="Use `as_str` instead")]
68120
pub fn as_string(&self) -> JsonResult<&String> {
69121
match *self {
@@ -79,13 +131,6 @@ impl JsonValue {
79131
}
80132
}
81133

82-
pub fn is_number(&self) -> bool {
83-
match *self {
84-
JsonValue::Number(_) => true,
85-
_ => false,
86-
}
87-
}
88-
89134
#[deprecated(since="0.6.1", note="Use `as_f64` instead")]
90135
pub fn as_number(&self) -> JsonResult<&f64> {
91136
match *self {
@@ -145,10 +190,10 @@ impl JsonValue {
145190
self.as_f64().and_then(|value| f64_to_singed!(isize, value))
146191
}
147192

148-
pub fn is_boolean(&self) -> bool {
193+
pub fn as_bool(&self) -> Option<bool> {
149194
match *self {
150-
JsonValue::Boolean(_) => true,
151-
_ => false
195+
JsonValue::Boolean(ref value) => Some(*value),
196+
_ => None
152197
}
153198
}
154199

@@ -160,34 +205,6 @@ impl JsonValue {
160205
}
161206
}
162207

163-
pub fn as_bool(&self) -> Option<bool> {
164-
match *self {
165-
JsonValue::Boolean(ref value) => Some(*value),
166-
_ => None
167-
}
168-
}
169-
170-
pub fn is_null(&self) -> bool {
171-
match *self {
172-
JsonValue::Null => true,
173-
_ => false,
174-
}
175-
}
176-
177-
pub fn is_object(&self) -> bool {
178-
match *self {
179-
JsonValue::Object(_) => true,
180-
_ => false,
181-
}
182-
}
183-
184-
pub fn is_array(&self) -> bool {
185-
match *self {
186-
JsonValue::Array(_) => true,
187-
_ => false,
188-
}
189-
}
190-
191208
/// Works on `JsonValue::Object` - create or override key with value.
192209
#[must_use]
193210
#[deprecated(since="0.6.0", note="Use `object[key] = value.into()` instead")]
@@ -262,6 +279,17 @@ impl JsonValue {
262279
}
263280
}
264281

282+
/// Works on `JsonValue::Array` - remove and return last element from
283+
/// an array. On failure returns a null.
284+
pub fn pop(&mut self) -> JsonValue {
285+
match *self {
286+
JsonValue::Array(ref mut vec) => {
287+
vec.pop().unwrap_or(JsonValue::Null)
288+
},
289+
_ => JsonValue::Null
290+
}
291+
}
292+
265293
/// Works on `JsonValue::Array` - gets a reference to a value at index.
266294
/// For most purposes consider using `array[index]` instead.
267295
#[deprecated(since="0.6.0", note="Use `array[index]` instead")]
@@ -358,6 +386,29 @@ impl JsonValue {
358386
_ => EntriesMut::None
359387
}
360388
}
389+
390+
/// Works on `JsonValue::Object` - remove a key and return the value it held.
391+
/// If the key was not present, the method is called on anything but an
392+
/// object, it will return a null.
393+
pub fn remove(&mut self, key: &str) -> JsonValue {
394+
match *self {
395+
JsonValue::Object(ref mut btree) => {
396+
btree.remove(key).unwrap_or(JsonValue::Null)
397+
},
398+
_ => JsonValue::Null
399+
}
400+
}
401+
402+
/// When called on an array or an object, will wipe them clean. When called
403+
/// on a string will clear the string. Numbers and booleans become null.
404+
pub fn clear(&mut self) {
405+
match *self {
406+
JsonValue::String(ref mut string) => string.clear(),
407+
JsonValue::Object(ref mut btree) => btree.clear(),
408+
JsonValue::Array(ref mut vec) => vec.clear(),
409+
_ => *self = JsonValue::Null,
410+
}
411+
}
361412
}
362413

363414
/// Implements indexing by `usize` to easily access array members:
@@ -411,7 +462,7 @@ impl IndexMut<usize> for JsonValue {
411462
_ => {
412463
*self = JsonValue::new_array();
413464
self.push(JsonValue::Null).unwrap();
414-
&mut self[0]
465+
self.index_mut(index)
415466
}
416467
}
417468
}
@@ -470,7 +521,7 @@ impl<'a> IndexMut<&'a str> for JsonValue {
470521
},
471522
_ => {
472523
*self = JsonValue::new_object();
473-
&mut self[index]
524+
self.index_mut(index)
474525
}
475526
}
476527
}

0 commit comments

Comments
 (0)