Skip to content

Commit cba26e6

Browse files
authored
Merge pull request #20 from maciejhirsz/0.6.1
0.6.1 bug fixes and type casts (fixes #4, closes #9)
2 parents 334efd9 + 81644f0 commit cba26e6

File tree

6 files changed

+188
-78
lines changed

6 files changed

+188
-78
lines changed

Cargo.toml

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

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
![](http://terhix.com/doc/json-rust-logo-small.png)
22

3-
# JSON in Rust
3+
# json-rust
44

5-
Parse and serialize JSON with ease.
5+
Parse and serialize [JSON](http://json.org/) with ease.
66

77
**[Complete Documentation](http://terhix.com/doc/json/) - [Cargo](https://crates.io/crates/json) - [Repository](https://github.com/maciejhirsz/json-rust)**
88

9-
# Why?
9+
## Why?
1010

1111
JSON is a very loose format where anything goes - arrays can hold mixed
1212
types, object keys can change types between API calls or not include

src/lib.rs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! ![](http://terhix.com/doc/json-rust-logo-small.png)
22
//!
3-
//! # JSON in Rust
3+
//! # json-rust
44
//!
5-
//! Parse and serialize JSON with ease.
5+
//! Parse and serialize [JSON](http://json.org/) with ease.
66
//!
77
//! **[Complete Documentation](http://terhix.com/doc/json/) - [Cargo](https://crates.io/crates/json) - [Repository](https://github.com/maciejhirsz/json-rust)**
88
//!
9-
//! # Why?
9+
//! ## Why?
1010
//!
1111
//! JSON is a very loose format where anything goes - arrays can hold mixed
1212
//! types, object keys can change types between API calls or not include
@@ -139,7 +139,7 @@
139139
//! data.push("foo");
140140
//! data.push(false);
141141
//!
142-
//! assert_eq!(json::stringify(data), "[10,\"foo\",false]");
142+
//! assert_eq!(data.dump(), r#"[10,"foo",false]"#);
143143
//! ```
144144
//!
145145
//! Putting fields on objects:
@@ -150,7 +150,7 @@
150150
//! data["answer"] = 42.into();
151151
//! data["foo"] = "bar".into();
152152
//!
153-
//! assert_eq!(json::stringify(data), "{\"answer\":42,\"foo\":\"bar\"}");
153+
//! assert_eq!(data.dump(), r#"{"answer":42,"foo":"bar"}"#);
154154
//! ```
155155
//!
156156
//! `array!` macro:
@@ -159,7 +159,7 @@
159159
//! # #[macro_use] extern crate json;
160160
//! # fn main() {
161161
//! let data = array!["foo", "bar", 100, true, json::Null];
162-
//! assert_eq!(json::stringify(data), "[\"foo\",\"bar\",100,true,null]");
162+
//! assert_eq!(data.dump(), r#"["foo","bar",100,true,null]"#);
163163
//! # }
164164
//! ```
165165
//!
@@ -174,10 +174,10 @@
174174
//! "canJSON" => true
175175
//! };
176176
//! assert_eq!(
177-
//! json::stringify(data),
177+
//! data.dump(),
178178
//! // Because object is internally using a BTreeMap,
179179
//! // the key order is alphabetical
180-
//! "{\"age\":30,\"canJSON\":true,\"name\":\"John Doe\"}"
180+
//! r#"{"age":30,"canJSON":true,"name":"John Doe"}"#
181181
//! );
182182
//! # }
183183
//! ```
@@ -296,27 +296,27 @@ macro_rules! object {
296296

297297
macro_rules! implement_extras {
298298
($from:ty) => {
299-
impl Into<JsonValue> for Option<$from> {
300-
fn into(self) -> JsonValue {
301-
match self {
299+
impl From<Option<$from>> for JsonValue {
300+
fn from(val: Option<$from>) -> JsonValue {
301+
match val {
302302
Some(value) => value.into(),
303303
None => Null,
304304
}
305305
}
306306
}
307307

308-
impl Into<JsonValue> for Vec<$from> {
309-
fn into(mut self) -> JsonValue {
310-
JsonValue::Array(self.drain(..)
308+
impl From<Vec<$from>> for JsonValue {
309+
fn from(mut val: Vec<$from>) -> JsonValue {
310+
JsonValue::Array(val.drain(..)
311311
.map(|value| value.into())
312312
.collect::<Vec<JsonValue>>()
313313
)
314314
}
315315
}
316316

317-
impl Into<JsonValue> for Vec<Option<$from>> {
318-
fn into(mut self) -> JsonValue {
319-
JsonValue::Array(self.drain(..)
317+
impl From<Vec<Option<$from>>> for JsonValue {
318+
fn from(mut val: Vec<Option<$from>>) -> JsonValue {
319+
JsonValue::Array(val.drain(..)
320320
.map(|item| item.into())
321321
.collect::<Vec<JsonValue>>()
322322
)
@@ -327,64 +327,64 @@ macro_rules! implement_extras {
327327

328328
macro_rules! implement {
329329
($to:ident, $from:ty as $wanted:ty) => {
330-
impl Into<JsonValue> for $from {
331-
fn into(self) -> JsonValue {
332-
JsonValue::$to(self as $wanted)
330+
impl From<$from> for JsonValue {
331+
fn from(val: $from) -> JsonValue {
332+
JsonValue::$to(val as $wanted)
333333
}
334334
}
335335

336336
implement_extras!($from);
337337
};
338338
($to:ident, $from:ty) => {
339-
impl Into<JsonValue> for $from {
340-
fn into(self) -> JsonValue {
341-
JsonValue::$to(self)
339+
impl From<$from> for JsonValue {
340+
fn from(val: $from) -> JsonValue {
341+
JsonValue::$to(val)
342342
}
343343
}
344344

345345
implement_extras!($from);
346346
}
347347
}
348348

349-
impl<'a> Into<JsonValue> for &'a str {
350-
fn into(self) -> JsonValue {
351-
JsonValue::String(self.to_string())
349+
impl<'a> From<&'a str> for JsonValue {
350+
fn from(val: &'a str) -> JsonValue {
351+
JsonValue::String(val.to_string())
352352
}
353353
}
354354

355-
impl<'a> Into<JsonValue> for Option<&'a str> {
356-
fn into(self) -> JsonValue {
357-
match self {
355+
impl<'a> From<Option<&'a str>> for JsonValue {
356+
fn from(val: Option<&'a str>) -> JsonValue {
357+
match val {
358358
Some(value) => value.into(),
359359
None => Null,
360360
}
361361
}
362362
}
363363

364-
impl Into<JsonValue> for HashMap<String, JsonValue> {
365-
fn into(mut self) -> JsonValue {
364+
impl From<HashMap<String, JsonValue>> for JsonValue {
365+
fn from(mut val: HashMap<String, JsonValue>) -> JsonValue {
366366
let mut object = BTreeMap::new();
367367

368-
for (key, value) in self.drain() {
368+
for (key, value) in val.drain() {
369369
object.insert(key, value);
370370
}
371371

372372
JsonValue::Object(object)
373373
}
374374
}
375375

376-
impl Into<JsonValue> for Option<HashMap<String, JsonValue>> {
377-
fn into(self) -> JsonValue {
378-
match self {
376+
impl From<Option<HashMap<String, JsonValue>>> for JsonValue {
377+
fn from(val: Option<HashMap<String, JsonValue>>) -> JsonValue {
378+
match val {
379379
Some(value) => value.into(),
380380
None => Null,
381381
}
382382
}
383383
}
384384

385-
impl Into<JsonValue> for Option<JsonValue> {
386-
fn into(self) -> JsonValue {
387-
match self {
385+
impl From<Option<JsonValue>> for JsonValue {
386+
fn from(val: Option<JsonValue>) -> JsonValue {
387+
match val {
388388
Some(value) => value,
389389
None => Null,
390390
}

src/parser.rs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,6 @@ use std::iter::{ Peekable, Iterator };
44
use std::collections::BTreeMap;
55
use { JsonValue, JsonError, JsonResult };
66

7-
macro_rules! expect {
8-
($tokenizer:ident, $p:pat) => (
9-
match $tokenizer.next() {
10-
Some($p) => {},
11-
token => panic!("WAT"),
12-
}
13-
)
14-
}
15-
167
#[derive(Debug)]
178
pub enum Token {
189
Comma,
@@ -137,7 +128,7 @@ impl<'a> Tokenizer<'a> {
137128
}
138129
}
139130

140-
fn read_number(&mut self, first: char) -> f64 {
131+
fn read_number(&mut self, first: char) -> JsonResult<f64> {
141132
self.buffer.clear();
142133
self.buffer.push(first);
143134
self.read_digits_to_buffer();
@@ -148,7 +139,7 @@ impl<'a> Tokenizer<'a> {
148139
match ch {
149140
'.' => {
150141
if period {
151-
panic!("Invalid character `{:?}`", ch);
142+
return Err(JsonError::UnexpectedCharacter(ch));
152143
}
153144
period = true;
154145
self.buffer.push(ch);
@@ -171,43 +162,41 @@ impl<'a> Tokenizer<'a> {
171162
}
172163
}
173164

174-
self.buffer.parse::<f64>().unwrap()
165+
Ok(self.buffer.parse::<f64>().unwrap())
175166
}
176-
}
177167

178-
impl<'a> Iterator for Tokenizer<'a> {
179-
type Item = Token;
180-
181-
fn next(&mut self) -> Option<Token> {
182-
'lex: while let Some(ch) = self.source.next() {
183-
return Some(match ch {
168+
fn next(&mut self) -> JsonResult<Token> {
169+
while let Some(ch) = self.source.next() {
170+
return Ok(match ch {
184171
',' => Token::Comma,
185172
':' => Token::Colon,
186173
'[' => Token::BracketOn,
187174
']' => Token::BracketOff,
188175
'{' => Token::BraceOn,
189176
'}' => Token::BraceOff,
190-
'"' => Token::String(self.read_string(ch).unwrap()),
191-
'0'...'9' | '-' => Token::Number(self.read_number(ch)),
177+
'"' => Token::String(try!(self.read_string(ch))),
178+
'0'...'9' | '-' => Token::Number(try!(self.read_number(ch))),
192179
'a'...'z' => {
193180
let label = self.read_label(ch);
194181
match label.as_ref() {
195182
"true" => Token::Boolean(true),
196183
"false" => Token::Boolean(false),
197184
"null" => Token::Null,
198-
_ => panic!("Invalid label `{:?}`", label)
185+
_ => {
186+
return Err(JsonError::UnexpectedToken(label.clone()));
187+
}
199188
}
200189
},
201190
_ => {
202191
if ch.is_whitespace() {
203-
continue 'lex;
192+
continue;
204193
} else {
205-
panic!("Invalid character `{:?}`", ch);
194+
return Err(JsonError::UnexpectedCharacter(ch));
206195
}
207196
}
208197
});
209198
}
210-
None
199+
Err(JsonError::UnexpectedEndOfJson)
211200
}
212201
}
213202

@@ -238,17 +227,15 @@ impl<'a> Parser<'a> {
238227
}
239228

240229
fn consume(&mut self) -> JsonResult<Token> {
241-
match self.tokenizer.next() {
242-
Some(token) => Ok(token),
243-
None => Err(JsonError::UnexpectedEndOfJson)
244-
}
230+
self.tokenizer.next()
245231
}
246232

247233
#[must_use]
248234
fn ensure_end(&mut self) -> JsonResult<()> {
249235
match self.tokenizer.next() {
250-
Some(token) => Err(JsonError::unexpected_token(token)),
251-
None => Ok(())
236+
Ok(token) => Err(JsonError::unexpected_token(token)),
237+
Err(JsonError::UnexpectedEndOfJson) => Ok(()),
238+
Err(error) => Err(error)
252239
}
253240
}
254241

0 commit comments

Comments
 (0)