blob: dce4f421caa48d3908c43d3299b0e38076277920 [file] [log] [blame]
Graydon Hoare00c856c2012-12-04 00:48:011// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
Elly Jones656a2af2011-11-07 23:24:4411// Rust JSON serialization library
12// Copyright (c) 2011 Google Inc.
Kevin Cantuc43426e2012-09-13 05:09:5513#[forbid(non_camel_case_types)];
Elly Jonesbd726262011-11-07 19:01:2814
Gareth Daniel Smithbe014162012-07-04 21:53:1215//! json serialization
Brian Anderson95521c42012-03-08 02:17:3016
Patrick Waltoneb4d39e2013-01-26 00:57:3917use serialize::Encodable;
Patrick Walton57c59992012-12-23 22:41:3718use serialize;
Patrick Walton22b87572012-09-08 01:53:1419use sort::Sort;
Elly Jonesbd726262011-11-07 19:01:2820
Patrick Walton57c59992012-12-23 22:41:3721use core::char;
22use core::cmp::{Eq, Ord};
23use core::float;
24use core::io::{WriterUtil, ReaderUtil};
25use core::io;
Patrick Walton2db3abd2013-01-09 03:37:2526use core::prelude::*;
Daniel Micay7f0fa142013-01-23 22:06:3227use core::hashmap::linear::LinearMap;
Patrick Walton57c59992012-12-23 22:41:3728use core::str;
29use core::to_str;
30use core::vec;
31
Gareth Daniel Smithbe014162012-07-04 21:53:1232/// Represents a json value
Erick Tryzelaar49d00b22012-09-24 16:55:4233pub enum Json {
34 Number(float),
35 String(~str),
Ben Striegela605fd02012-08-11 14:08:4236 Boolean(bool),
Erick Tryzelaar49d00b22012-09-24 16:55:4237 List(List),
38 Object(~Object),
Ben Striegela605fd02012-08-11 14:08:4239 Null,
Elly Jonesbd726262011-11-07 19:01:2840}
41
Erick Tryzelaar49d00b22012-09-24 16:55:4242pub type List = ~[Json];
Daniel Micay7f0fa142013-01-23 22:06:3243pub type Object = LinearMap<~str, Json>;
Erick Tryzelaar49d00b22012-09-24 16:55:4244
45pub struct Error {
Erick Tryzelaar012dec52012-02-26 00:39:3246 line: uint,
47 col: uint,
Michael Sullivan92743dc2012-07-14 05:57:4848 msg: @~str,
Kevin Cantud47cb102012-08-30 23:39:5649}
50
Kevin Cantuc43426e2012-09-13 05:09:5551fn escape_str(s: &str) -> ~str {
Michael Sullivan92743dc2012-07-14 05:57:4852 let mut escaped = ~"\"";
Niko Matsakis9cf271f2012-09-19 04:41:3753 for str::chars_each(s) |c| {
Brian Andersonecaf9e32012-08-06 19:34:0854 match c {
Brian Anderson025d8662012-08-04 02:59:0455 '"' => escaped += ~"\\\"",
56 '\\' => escaped += ~"\\\\",
57 '\x08' => escaped += ~"\\b",
58 '\x0c' => escaped += ~"\\f",
59 '\n' => escaped += ~"\\n",
60 '\r' => escaped += ~"\\r",
61 '\t' => escaped += ~"\\t",
62 _ => escaped += str::from_char(c)
Erick Tryzelaarb361f6c2012-06-13 00:20:5163 }
64 };
65
Michael Sullivan92743dc2012-07-14 05:57:4866 escaped += ~"\"";
Erick Tryzelaarb361f6c2012-06-13 00:20:5167
68 escaped
69}
70
Erick Tryzelaar49d00b22012-09-24 16:55:4271fn spaces(n: uint) -> ~str {
72 let mut ss = ~"";
Tim Chevalier5a8ba072012-10-11 21:12:5073 for n.times { str::push_str(&mut ss, " "); }
Erick Tryzelaar49d00b22012-09-24 16:55:4274 return ss;
75}
76
Erick Tryzelaar8650c6f2012-12-18 03:31:0477pub struct Encoder {
Erick Tryzelaar49d00b22012-09-24 16:55:4278 priv wr: io::Writer,
79}
80
Erick Tryzelaar8650c6f2012-12-18 03:31:0481pub fn Encoder(wr: io::Writer) -> Encoder {
82 Encoder { wr: wr }
Erick Tryzelaar49d00b22012-09-24 16:55:4283}
84
Erick Tryzelaar8650c6f2012-12-18 03:31:0485pub impl Encoder: serialize::Encoder {
Erick Tryzelaar49d00b22012-09-24 16:55:4286 fn emit_nil(&self) { self.wr.write_str("null") }
87
88 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
89 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
90 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
91 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
92 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
93
94 fn emit_int(&self, v: int) { self.emit_float(v as float); }
95 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
96 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
97 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
98 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
99
100 fn emit_bool(&self, v: bool) {
101 if v {
102 self.wr.write_str("true");
103 } else {
104 self.wr.write_str("false");
105 }
106 }
107
108 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
109 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
110 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39111 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42112 }
113
Erick Tryzelaar81423a32012-09-27 04:35:13114 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
115
116 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
117 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
118 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
119
120 fn emit_borrowed(&self, f: fn()) { f() }
121 fn emit_owned(&self, f: fn()) { f() }
122 fn emit_managed(&self, f: fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42123
John Clements394f8ee2013-02-07 01:23:41124 fn emit_enum(&self, _name: &str, f: fn()) {
John Clementsfe823742013-02-07 01:19:11125 f()
126 }
John Clements394f8ee2013-02-07 01:23:41127
128 fn emit_enum_variant(&self, name: &str, _id: uint, _cnt: uint, f: fn()) {
John Clements76596142013-02-07 00:20:41129 // emitting enums as arrays where the first
130 // element provides the enum variant name
131 self.wr.write_char('[');
John Clements394f8ee2013-02-07 01:23:41132 self.wr.write_str(escape_str(name));
John Clements76596142013-02-07 00:20:41133 f();
134 self.wr.write_char(']');
Erick Tryzelaar49d00b22012-09-24 16:55:42135 }
John Clementsf91160b2013-02-08 01:06:26136
137 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
John Clements0e9495b2013-02-07 22:39:02138 self.wr.write_char(',');
John Clementsfe823742013-02-07 01:19:11139 f();
Erick Tryzelaar49d00b22012-09-24 16:55:42140 }
141
Erick Tryzelaar81423a32012-09-27 04:35:13142 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42143 self.wr.write_char('[');
144 f();
145 self.wr.write_char(']');
146 }
Erick Tryzelaar81423a32012-09-27 04:35:13147 fn emit_owned_vec(&self, len: uint, f: fn()) {
148 self.emit_borrowed_vec(len, f)
149 }
150 fn emit_managed_vec(&self, len: uint, f: fn()) {
151 self.emit_borrowed_vec(len, f)
152 }
Erick Tryzelaar49d00b22012-09-24 16:55:42153 fn emit_vec_elt(&self, idx: uint, f: fn()) {
154 if idx != 0 { self.wr.write_char(','); }
155 f()
156 }
157
Erick Tryzelaar49d00b22012-09-24 16:55:42158 fn emit_rec(&self, f: fn()) {
159 self.wr.write_char('{');
160 f();
161 self.wr.write_char('}');
162 }
Michael Neumann2b6c4562012-12-27 12:16:16163 fn emit_struct(&self, _name: &str, _len: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13164 self.wr.write_char('{');
165 f();
166 self.wr.write_char('}');
167 }
168 fn emit_field(&self, name: &str, idx: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42169 if idx != 0 { self.wr.write_char(','); }
170 self.wr.write_str(escape_str(name));
171 self.wr.write_char(':');
172 f();
173 }
Erick Tryzelaar81423a32012-09-27 04:35:13174
175 fn emit_tup(&self, len: uint, f: fn()) {
176 self.emit_borrowed_vec(len, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42177 }
178 fn emit_tup_elt(&self, idx: uint, f: fn()) {
179 self.emit_vec_elt(idx, f)
180 }
181}
182
Erick Tryzelaar8650c6f2012-12-18 03:31:04183pub struct PrettyEncoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42184 priv wr: io::Writer,
185 priv mut indent: uint,
186}
187
Erick Tryzelaar8650c6f2012-12-18 03:31:04188pub fn PrettyEncoder(wr: io::Writer) -> PrettyEncoder {
189 PrettyEncoder { wr: wr, indent: 0 }
Erick Tryzelaar49d00b22012-09-24 16:55:42190}
191
Erick Tryzelaar8650c6f2012-12-18 03:31:04192pub impl PrettyEncoder: serialize::Encoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42193 fn emit_nil(&self) { self.wr.write_str("null") }
194
195 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
196 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
197 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
198 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
199 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
200
201 fn emit_int(&self, v: int) { self.emit_float(v as float); }
202 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
203 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
204 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
205 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
206
207 fn emit_bool(&self, v: bool) {
208 if v {
209 self.wr.write_str("true");
210 } else {
211 self.wr.write_str("false");
212 }
213 }
214
215 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
216 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
217 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39218 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42219 }
220
Erick Tryzelaar81423a32012-09-27 04:35:13221 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
222
223 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
224 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
225 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
226
227 fn emit_borrowed(&self, f: fn()) { f() }
228 fn emit_owned(&self, f: fn()) { f() }
229 fn emit_managed(&self, f: fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42230
231 fn emit_enum(&self, name: &str, f: fn()) {
Nick Desaulniersaee79292013-02-01 01:51:01232 if name != "option" { die!(~"only supports option enum") }
Erick Tryzelaar49d00b22012-09-24 16:55:42233 f()
234 }
235 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
236 if id == 0 {
237 self.emit_nil();
238 } else {
239 f()
240 }
241 }
242 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
243 f()
244 }
245
Erick Tryzelaar81423a32012-09-27 04:35:13246 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42247 self.wr.write_char('[');
248 self.indent += 2;
249 f();
250 self.indent -= 2;
251 self.wr.write_char(']');
252 }
Erick Tryzelaar81423a32012-09-27 04:35:13253 fn emit_owned_vec(&self, len: uint, f: fn()) {
254 self.emit_borrowed_vec(len, f)
255 }
256 fn emit_managed_vec(&self, len: uint, f: fn()) {
257 self.emit_borrowed_vec(len, f)
258 }
Erick Tryzelaar49d00b22012-09-24 16:55:42259 fn emit_vec_elt(&self, idx: uint, f: fn()) {
260 if idx == 0 {
261 self.wr.write_char('\n');
262 } else {
263 self.wr.write_str(",\n");
264 }
265 self.wr.write_str(spaces(self.indent));
266 f()
267 }
268
Erick Tryzelaar49d00b22012-09-24 16:55:42269 fn emit_rec(&self, f: fn()) {
270 self.wr.write_char('{');
271 self.indent += 2;
272 f();
273 self.indent -= 2;
274 self.wr.write_char('}');
275 }
Michael Neumann2b6c4562012-12-27 12:16:16276 fn emit_struct(&self, _name: &str, _len: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13277 self.emit_rec(f)
278 }
279 fn emit_field(&self, name: &str, idx: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42280 if idx == 0 {
281 self.wr.write_char('\n');
282 } else {
283 self.wr.write_str(",\n");
284 }
285 self.wr.write_str(spaces(self.indent));
286 self.wr.write_str(escape_str(name));
287 self.wr.write_str(": ");
288 f();
289 }
290 fn emit_tup(&self, sz: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13291 self.emit_borrowed_vec(sz, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42292 }
293 fn emit_tup_elt(&self, idx: uint, f: fn()) {
294 self.emit_vec_elt(idx, f)
295 }
296}
297
Erick Tryzelaar8650c6f2012-12-18 03:31:04298pub impl<S: serialize::Encoder> Json: serialize::Encodable<S> {
299 fn encode(&self, s: &S) {
Erick Tryzelaarab89b5c2012-10-13 16:11:33300 match *self {
Erick Tryzelaar8650c6f2012-12-18 03:31:04301 Number(v) => v.encode(s),
302 String(ref v) => v.encode(s),
303 Boolean(v) => v.encode(s),
304 List(ref v) => v.encode(s),
Erick Tryzelaarab89b5c2012-10-13 16:11:33305 Object(ref v) => {
306 do s.emit_rec || {
307 let mut idx = 0;
Daniel Micay9599cc82013-02-08 02:03:13308 for v.each |&(key, value)| {
Erick Tryzelaarab89b5c2012-10-13 16:11:33309 do s.emit_field(*key, idx) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04310 value.encode(s);
Erick Tryzelaarab89b5c2012-10-13 16:11:33311 }
312 idx += 1;
313 }
314 }
315 },
316 Null => s.emit_nil(),
317 }
318 }
319}
320
Erick Tryzelaar8650c6f2012-12-18 03:31:04321/// Encodes a json value into a io::writer
Erick Tryzelaar49d00b22012-09-24 16:55:42322pub fn to_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04323 json.encode(&Encoder(wr))
Erick Tryzelaar49d00b22012-09-24 16:55:42324}
325
Erick Tryzelaar8650c6f2012-12-18 03:31:04326/// Encodes a json value into a string
Patrick Walton54b2cad2013-01-23 19:43:58327pub pure fn to_str(json: &Json) -> ~str {
328 unsafe {
329 // ugh, should be safe
330 io::with_str_writer(|wr| to_writer(wr, json))
331 }
Elly Jonesbd726262011-11-07 19:01:28332}
333
Erick Tryzelaar8650c6f2012-12-18 03:31:04334/// Encodes a json value into a io::writer
Erick Tryzelaar49d00b22012-09-24 16:55:42335pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04336 json.encode(&PrettyEncoder(wr))
Kevin Cantud47cb102012-08-30 23:39:56337}
338
Erick Tryzelaar8650c6f2012-12-18 03:31:04339/// Encodes a json value into a string
Erick Tryzelaar49d00b22012-09-24 16:55:42340pub fn to_pretty_str(json: &Json) -> ~str {
341 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40342}
343
Erick Tryzelaar49d00b22012-09-24 16:55:42344pub struct Parser {
345 priv rdr: io::Reader,
346 priv mut ch: char,
347 priv mut line: uint,
348 priv mut col: uint,
349}
350
Erick Tryzelaar8650c6f2012-12-18 03:31:04351/// Decode a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42352pub fn Parser(rdr: io::Reader) -> Parser {
353 Parser {
354 rdr: rdr,
355 ch: rdr.read_char(),
Tim Chevalier90d06b82012-09-19 05:35:42356 line: 1,
357 col: 1,
Erick Tryzelaar49d00b22012-09-24 16:55:42358 }
359}
360
361pub impl Parser {
362 fn parse() -> Result<Json, Error> {
363 match move self.parse_value() {
364 Ok(move value) => {
365 // Skip trailing whitespaces.
366 self.parse_whitespace();
367 // Make sure there is no trailing characters.
368 if self.eof() {
Tim Chevalier90d06b82012-09-19 05:35:42369 Ok(move value)
Erick Tryzelaar49d00b22012-09-24 16:55:42370 } else {
371 self.error(~"trailing characters")
372 }
373 }
374 Err(move e) => Err(e)
375 }
376 }
377}
378
379priv impl Parser {
Erick Tryzelaar012dec52012-02-26 00:39:32380 fn eof() -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28381
Erick Tryzelaar012dec52012-02-26 00:39:32382 fn bump() {
383 self.ch = self.rdr.read_char();
384
385 if self.ch == '\n' {
386 self.line += 1u;
387 self.col = 1u;
388 } else {
389 self.col += 1u;
390 }
Elly Jonesbd726262011-11-07 19:01:28391 }
392
Erick Tryzelaar012dec52012-02-26 00:39:32393 fn next_char() -> char {
394 self.bump();
395 self.ch
Elly Jonesbd726262011-11-07 19:01:28396 }
397
Tim Chevalierf33539e2012-10-03 19:21:48398 fn error<T>(msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42399 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28400 }
Elly Jonesbd726262011-11-07 19:01:28401
Ben Striegela605fd02012-08-11 14:08:42402 fn parse_value() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32403 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28404
Brian Andersonb3559362012-08-02 00:30:05405 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32406
Brian Andersonecaf9e32012-08-06 19:34:08407 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42408 'n' => self.parse_ident(~"ull", Null),
409 't' => self.parse_ident(~"rue", Boolean(true)),
410 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05411 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42412 '"' =>
413 match move self.parse_str() {
414 Ok(move s) => Ok(String(s)),
415 Err(move e) => Err(e),
416 },
Brian Anderson025d8662012-08-04 02:59:04417 '[' => self.parse_list(),
418 '{' => self.parse_object(),
419 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32420 }
421 }
422
423 fn parse_whitespace() {
424 while char::is_whitespace(self.ch) { self.bump(); }
425 }
426
Tim Chevalier8fc60af2012-10-05 02:58:31427 fn parse_ident(ident: &str, value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07428 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32429 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42430 Ok(move value)
Erick Tryzelaar012dec52012-02-26 00:39:32431 } else {
Michael Sullivan92743dc2012-07-14 05:57:48432 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32433 }
434 }
435
Ben Striegela605fd02012-08-11 14:08:42436 fn parse_number() -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56437 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32438
439 if self.ch == '-' {
440 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00441 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28442 }
Elly Jonesbd726262011-11-07 19:01:28443
Brian Andersonecaf9e32012-08-06 19:34:08444 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31445 Ok(res) => res,
446 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32447 };
448
449 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08450 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31451 Ok(r) => res = r,
452 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28453 }
Elly Jonesbd726262011-11-07 19:01:28454 }
Erick Tryzelaar012dec52012-02-26 00:39:32455
456 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08457 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31458 Ok(r) => res = r,
459 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32460 }
461 }
462
Erick Tryzelaar49d00b22012-09-24 16:55:42463 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28464 }
465
Ben Striegela605fd02012-08-11 14:08:42466 fn parse_integer() -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56467 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32468
Brian Andersonecaf9e32012-08-06 19:34:08469 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04470 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32471 self.bump();
472
473 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08474 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05475 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04476 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32477 }
478 }
Brian Anderson80c4f742012-09-02 01:38:05479 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32480 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08481 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05482 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32483 res *= 10f;
484 res += ((self.ch as int) - ('0' as int)) as float;
485
486 self.bump();
487 }
Brian Anderson025d8662012-08-04 02:59:04488 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32489 }
490 }
491 }
Brian Anderson025d8662012-08-04 02:59:04492 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32493 }
494
Brian Anderson0c6e4702012-08-26 23:54:31495 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28496 }
497
Ben Striegela605fd02012-08-11 14:08:42498 fn parse_decimal(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32499 self.bump();
500
501 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08502 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05503 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04504 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32505 }
506
Niko Matsakis6b358752012-03-14 18:03:56507 let mut res = res;
508 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32509 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08510 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05511 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00512 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32513 res += (((self.ch as int) - ('0' as int)) as float) * dec;
514
515 self.bump();
516 }
Brian Anderson025d8662012-08-04 02:59:04517 _ => break
Elly Jonesbd726262011-11-07 19:01:28518 }
Elly Jonesbd726262011-11-07 19:01:28519 }
Elly Jonesbd726262011-11-07 19:01:28520
Brian Anderson0c6e4702012-08-26 23:54:31521 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32522 }
523
Ben Striegela605fd02012-08-11 14:08:42524 fn parse_exponent(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32525 self.bump();
526
Niko Matsakis6b358752012-03-14 18:03:56527 let mut res = res;
528 let mut exp = 0u;
529 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32530
Brian Andersonecaf9e32012-08-06 19:34:08531 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04532 '+' => self.bump(),
533 '-' => { self.bump(); neg_exp = true; }
534 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32535 }
536
537 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08538 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05539 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04540 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32541 }
542
543 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08544 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05545 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32546 exp *= 10u;
547 exp += (self.ch as uint) - ('0' as uint);
548
549 self.bump();
550 }
Brian Anderson025d8662012-08-04 02:59:04551 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32552 }
553 }
554
555 let exp = float::pow_with_uint(10u, exp);
556 if neg_exp {
557 res /= exp;
558 } else {
559 res *= exp;
560 }
561
Brian Anderson0c6e4702012-08-26 23:54:31562 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32563 }
564
Erick Tryzelaar49d00b22012-09-24 16:55:42565 fn parse_str() -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56566 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48567 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32568
569 while !self.eof() {
570 self.bump();
571
572 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08573 match self.ch {
Tim Chevalier5a8ba072012-10-11 21:12:50574 '"' => str::push_char(&mut res, '"'),
575 '\\' => str::push_char(&mut res, '\\'),
576 '/' => str::push_char(&mut res, '/'),
577 'b' => str::push_char(&mut res, '\x08'),
578 'f' => str::push_char(&mut res, '\x0c'),
579 'n' => str::push_char(&mut res, '\n'),
580 'r' => str::push_char(&mut res, '\r'),
581 't' => str::push_char(&mut res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04582 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32583 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56584 let mut i = 0u;
585 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32586 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08587 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05588 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10589 n = n * 16u + (self.ch as uint)
590 - ('0' as uint);
591 },
592 'a' | 'A' => n = n * 16u + 10u,
593 'b' | 'B' => n = n * 16u + 11u,
594 'c' | 'C' => n = n * 16u + 12u,
595 'd' | 'D' => n = n * 16u + 13u,
596 'e' | 'E' => n = n * 16u + 14u,
597 'f' | 'F' => n = n * 16u + 15u,
598 _ => return self.error(
599 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32600 }
Niko Matsakis6b358752012-03-14 18:03:56601 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32602 }
603
604 // Error out if we didn't parse 4 digits.
605 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10606 return self.error(
607 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32608 }
609
Tim Chevalier5a8ba072012-10-11 21:12:50610 str::push_char(&mut res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32611 }
Brian Anderson025d8662012-08-04 02:59:04612 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32613 }
614 escape = false;
615 } else if self.ch == '\\' {
616 escape = true;
617 } else {
618 if self.ch == '"' {
619 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42620 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32621 }
Tim Chevalier5a8ba072012-10-11 21:12:50622 str::push_char(&mut res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32623 }
624 }
625
Michael Sullivan92743dc2012-07-14 05:57:48626 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32627 }
628
Ben Striegela605fd02012-08-11 14:08:42629 fn parse_list() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32630 self.bump();
631 self.parse_whitespace();
632
Michael Sullivan98e161f2012-06-29 23:26:56633 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32634
635 if self.ch == ']' {
636 self.bump();
Tim Chevalier90d06b82012-09-19 05:35:42637 return Ok(List(move values));
Erick Tryzelaar012dec52012-02-26 00:39:32638 }
639
Tim Chevalier35400e12012-03-11 04:34:17640 loop {
Erick Tryzelaar49d00b22012-09-24 16:55:42641 match move self.parse_value() {
Tim Chevalier90d06b82012-09-19 05:35:42642 Ok(move v) => values.push(move v),
Erick Tryzelaar49d00b22012-09-24 16:55:42643 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32644 }
645
646 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17647 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05648 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17649 }
Erick Tryzelaar012dec52012-02-26 00:39:32650
Brian Andersonecaf9e32012-08-06 19:34:08651 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04652 ',' => self.bump(),
Tim Chevalier90d06b82012-09-19 05:35:42653 ']' => { self.bump(); return Ok(List(move values)); }
Brian Anderson025d8662012-08-04 02:59:04654 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32655 }
Tim Chevalier35400e12012-03-11 04:34:17656 };
Erick Tryzelaar012dec52012-02-26 00:39:32657 }
658
Ben Striegela605fd02012-08-11 14:08:42659 fn parse_object() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32660 self.bump();
661 self.parse_whitespace();
662
Daniel Micay7f0fa142013-01-23 22:06:32663 let mut values = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:32664
665 if self.ch == '}' {
666 self.bump();
Tim Chevalier90d06b82012-09-19 05:35:42667 return Ok(Object(move values));
Erick Tryzelaar012dec52012-02-26 00:39:32668 }
669
670 while !self.eof() {
671 self.parse_whitespace();
672
673 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05674 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32675 }
676
Erick Tryzelaar49d00b22012-09-24 16:55:42677 let key = match move self.parse_str() {
678 Ok(move key) => key,
679 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32680 };
681
682 self.parse_whitespace();
683
684 if self.ch != ':' {
685 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05686 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32687 }
688 self.bump();
689
Erick Tryzelaar49d00b22012-09-24 16:55:42690 match move self.parse_value() {
Tim Chevalier90d06b82012-09-19 05:35:42691 Ok(move value) => { values.insert(key, move value); }
Erick Tryzelaar49d00b22012-09-24 16:55:42692 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32693 }
694 self.parse_whitespace();
695
Brian Andersonecaf9e32012-08-06 19:34:08696 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04697 ',' => self.bump(),
Tim Chevalier90d06b82012-09-19 05:35:42698 '}' => { self.bump(); return Ok(Object(move values)); }
Brian Anderson025d8662012-08-04 02:59:04699 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32700 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05701 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32702 }
703 }
704 }
705
Brian Andersonb3559362012-08-02 00:30:05706 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28707 }
708}
709
Erick Tryzelaar8650c6f2012-12-18 03:31:04710/// Decodes a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42711pub fn from_reader(rdr: io::Reader) -> Result<Json, Error> {
712 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28713}
714
Erick Tryzelaar8650c6f2012-12-18 03:31:04715/// Decodes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42716pub fn from_str(s: &str) -> Result<Json, Error> {
717 do io::with_str_reader(s) |rdr| {
718 from_reader(rdr)
719 }
Erick Tryzelaar012dec52012-02-26 00:39:32720}
721
Erick Tryzelaar8650c6f2012-12-18 03:31:04722pub struct Decoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42723 priv json: Json,
724 priv mut stack: ~[&Json],
725}
726
Erick Tryzelaar8650c6f2012-12-18 03:31:04727pub fn Decoder(json: Json) -> Decoder {
728 Decoder { json: move json, stack: ~[] }
Elly Jonesbd726262011-11-07 19:01:28729}
Brian Anderson6e27b272012-01-18 03:05:07730
Erick Tryzelaar8650c6f2012-12-18 03:31:04731priv impl Decoder {
Niko Matsakis67a8e712012-09-27 00:33:34732 fn peek(&self) -> &self/Json {
733 if self.stack.len() == 0 { self.stack.push(&self.json); }
Erick Tryzelaar49d00b22012-09-24 16:55:42734 vec::last(self.stack)
735 }
736
Niko Matsakis67a8e712012-09-27 00:33:34737 fn pop(&self) -> &self/Json {
738 if self.stack.len() == 0 { self.stack.push(&self.json); }
Niko Matsakis21519bc2012-09-28 05:20:47739 self.stack.pop()
Erick Tryzelaar49d00b22012-09-24 16:55:42740 }
741}
742
Erick Tryzelaar8650c6f2012-12-18 03:31:04743pub impl Decoder: serialize::Decoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42744 fn read_nil(&self) -> () {
745 debug!("read_nil");
746 match *self.pop() {
747 Null => (),
Nick Desaulniersaee79292013-02-01 01:51:01748 _ => die!(~"not a null")
Erick Tryzelaar49d00b22012-09-24 16:55:42749 }
750 }
751
752 fn read_u64(&self) -> u64 { self.read_float() as u64 }
753 fn read_u32(&self) -> u32 { self.read_float() as u32 }
754 fn read_u16(&self) -> u16 { self.read_float() as u16 }
755 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
756 fn read_uint(&self) -> uint { self.read_float() as uint }
757
758 fn read_i64(&self) -> i64 { self.read_float() as i64 }
759 fn read_i32(&self) -> i32 { self.read_float() as i32 }
760 fn read_i16(&self) -> i16 { self.read_float() as i16 }
761 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
762 fn read_int(&self) -> int { self.read_float() as int }
763
764 fn read_bool(&self) -> bool {
765 debug!("read_bool");
766 match *self.pop() {
767 Boolean(b) => b,
Nick Desaulniersaee79292013-02-01 01:51:01768 _ => die!(~"not a boolean")
Erick Tryzelaar49d00b22012-09-24 16:55:42769 }
770 }
771
772 fn read_f64(&self) -> f64 { self.read_float() as f64 }
773 fn read_f32(&self) -> f32 { self.read_float() as f32 }
774 fn read_float(&self) -> float {
775 debug!("read_float");
776 match *self.pop() {
777 Number(f) => f,
Nick Desaulniersaee79292013-02-01 01:51:01778 _ => die!(~"not a number")
Erick Tryzelaar49d00b22012-09-24 16:55:42779 }
780 }
781
Erick Tryzelaar81423a32012-09-27 04:35:13782 fn read_char(&self) -> char {
783 let v = str::chars(self.read_owned_str());
Nick Desaulniersaee79292013-02-01 01:51:01784 if v.len() != 1 { die!(~"string must have one character") }
Erick Tryzelaar81423a32012-09-27 04:35:13785 v[0]
786 }
787
788 fn read_owned_str(&self) -> ~str {
789 debug!("read_owned_str");
Erick Tryzelaar49d00b22012-09-24 16:55:42790 match *self.pop() {
791 String(ref s) => copy *s,
Nick Desaulniersaee79292013-02-01 01:51:01792 _ => die!(~"not a string")
Erick Tryzelaar49d00b22012-09-24 16:55:42793 }
794 }
795
Erick Tryzelaar81423a32012-09-27 04:35:13796 fn read_managed_str(&self) -> @str {
Huon Wilson76dc7812012-12-10 02:29:33797 debug!("read_managed_str");
798 match *self.pop() {
799 String(ref s) => s.to_managed(),
Nick Desaulniersaee79292013-02-01 01:51:01800 _ => die!(~"not a string")
Huon Wilson76dc7812012-12-10 02:29:33801 }
Erick Tryzelaar81423a32012-09-27 04:35:13802 }
803
804 fn read_owned<T>(&self, f: fn() -> T) -> T {
805 debug!("read_owned()");
806 f()
807 }
808
809 fn read_managed<T>(&self, f: fn() -> T) -> T {
810 debug!("read_managed()");
811 f()
812 }
813
Tim Chevalier9ff95e22012-10-01 19:36:06814 fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42815 debug!("read_enum(%s)", name);
Nick Desaulniersaee79292013-02-01 01:51:01816 if name != ~"option" { die!(~"only supports the option enum") }
Erick Tryzelaar49d00b22012-09-24 16:55:42817 f()
818 }
819
820 fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
821 debug!("read_enum_variant()");
822 let idx = match *self.peek() {
823 Null => 0,
824 _ => 1,
825 };
826 f(idx)
827 }
828
829 fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
830 debug!("read_enum_variant_arg(idx=%u)", idx);
Nick Desaulniersaee79292013-02-01 01:51:01831 if idx != 0 { die!(~"unknown index") }
Erick Tryzelaar49d00b22012-09-24 16:55:42832 f()
833 }
834
Erick Tryzelaar81423a32012-09-27 04:35:13835 fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
836 debug!("read_owned_vec()");
837 let len = match *self.peek() {
Niko Matsakisa380df82013-02-08 03:33:12838 List(ref list) => list.len(),
Nick Desaulniersaee79292013-02-01 01:51:01839 _ => die!(~"not a list"),
Erick Tryzelaar81423a32012-09-27 04:35:13840 };
841 let res = f(len);
842 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42843 move res
Erick Tryzelaar81423a32012-09-27 04:35:13844 }
845
846 fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
847 debug!("read_owned_vec()");
Erick Tryzelaar49d00b22012-09-24 16:55:42848 let len = match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34849 List(ref list) => list.len(),
Nick Desaulniersaee79292013-02-01 01:51:01850 _ => die!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42851 };
852 let res = f(len);
853 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42854 move res
Erick Tryzelaar49d00b22012-09-24 16:55:42855 }
856
857 fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
858 debug!("read_vec_elt(idx=%u)", idx);
859 match *self.peek() {
860 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34861 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42862 f()
863 }
Nick Desaulniersaee79292013-02-01 01:51:01864 _ => die!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42865 }
866 }
867
Erick Tryzelaar49d00b22012-09-24 16:55:42868 fn read_rec<T>(&self, f: fn() -> T) -> T {
869 debug!("read_rec()");
870 let value = f();
871 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42872 move value
Erick Tryzelaar49d00b22012-09-24 16:55:42873 }
874
Michael Neumann2b6c4562012-12-27 12:16:16875 fn read_struct<T>(&self, _name: &str, _len: uint, f: fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13876 debug!("read_struct()");
877 let value = f();
878 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42879 move value
Erick Tryzelaar81423a32012-09-27 04:35:13880 }
881
882 fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
883 debug!("read_rec_field(%s, idx=%u)", name, idx);
Erick Tryzelaar49d00b22012-09-24 16:55:42884 let top = self.peek();
885 match *top {
886 Object(ref obj) => {
Daniel Micayee0a8c62013-01-23 16:47:43887 match obj.find(&name.to_owned()) {
Nick Desaulniersaee79292013-02-01 01:51:01888 None => die!(fmt!("no such field: %s", name)),
Erick Tryzelaar49d00b22012-09-24 16:55:42889 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34890 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42891 f()
892 }
893 }
894 }
Nick Desaulniersaee79292013-02-01 01:51:01895 Number(_) => die!(~"num"),
896 String(_) => die!(~"str"),
897 Boolean(_) => die!(~"bool"),
898 List(_) => die!(fmt!("list: %?", top)),
899 Null => die!(~"null"),
Erick Tryzelaar49d00b22012-09-24 16:55:42900
Nick Desaulniersaee79292013-02-01 01:51:01901 //_ => die!(fmt!("not an object: %?", *top))
Erick Tryzelaar49d00b22012-09-24 16:55:42902 }
903 }
904
Erick Tryzelaar81423a32012-09-27 04:35:13905 fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
906 debug!("read_tup(len=%u)", len);
Erick Tryzelaar49d00b22012-09-24 16:55:42907 let value = f();
908 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42909 move value
Erick Tryzelaar49d00b22012-09-24 16:55:42910 }
911
912 fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
913 debug!("read_tup_elt(idx=%u)", idx);
914 match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34915 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34916 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42917 f()
918 }
Nick Desaulniersaee79292013-02-01 01:51:01919 _ => die!(~"not a list")
Erick Tryzelaar49d00b22012-09-24 16:55:42920 }
921 }
922}
923
924impl Json : Eq {
Patrick Walton318e5342012-11-15 02:59:30925 pure fn eq(&self, other: &Json) -> bool {
Tim Chevalier3e7da962013-01-11 04:09:16926 match (self) {
927 &Number(f0) =>
928 match other { &Number(f1) => f0 == f1, _ => false },
929 &String(ref s0) =>
930 match other { &String(ref s1) => s0 == s1, _ => false },
931 &Boolean(b0) =>
932 match other { &Boolean(b1) => b0 == b1, _ => false },
933 &Null =>
934 match other { &Null => true, _ => false },
935 &List(ref v0) =>
936 match other { &List(ref v1) => v0 == v1, _ => false },
937 &Object(ref d0) => {
938 match other {
939 &Object(ref d1) => {
Patrick Walton318e5342012-11-15 02:59:30940 if d0.len() == d1.len() {
941 let mut equal = true;
Daniel Micay9599cc82013-02-08 02:03:13942 for d0.each |&(k, v0)| {
Daniel Micayee0a8c62013-01-23 16:47:43943 match d1.find(k) {
Patrick Walton318e5342012-11-15 02:59:30944 Some(v1) if v0 == v1 => { },
945 _ => { equal = false; break }
946 }
947 };
948 equal
949 } else {
950 false
951 }
952 }
953 _ => false
954 }
955 }
956 }
957 }
Tim Chevalier3e7da962013-01-11 04:09:16958 pure fn ne(&self, other: &Json) -> bool { !self.eq(other) }
Erick Tryzelaar49d00b22012-09-24 16:55:42959}
960
Patrick Walton22b87572012-09-08 01:53:14961/// Test if two json values are less than one another
Erick Tryzelaar49d00b22012-09-24 16:55:42962impl Json : Ord {
Patrick Walton318e5342012-11-15 02:59:30963 pure fn lt(&self, other: &Json) -> bool {
964 match (*self) {
965 Number(f0) => {
966 match *other {
967 Number(f1) => f0 < f1,
968 String(_) | Boolean(_) | List(_) | Object(_) |
969 Null => true
970 }
971 }
972
973 String(ref s0) => {
974 match *other {
975 Number(_) => false,
976 String(ref s1) => s0 < s1,
977 Boolean(_) | List(_) | Object(_) | Null => true
978 }
979 }
980
981 Boolean(b0) => {
982 match *other {
983 Number(_) | String(_) => false,
984 Boolean(b1) => b0 < b1,
985 List(_) | Object(_) | Null => true
986 }
987 }
988
Patrick Walton98fdcb02012-12-08 03:34:57989 List(ref l0) => {
Patrick Walton318e5342012-11-15 02:59:30990 match *other {
991 Number(_) | String(_) | Boolean(_) => false,
Patrick Walton98fdcb02012-12-08 03:34:57992 List(ref l1) => (*l0) < (*l1),
Patrick Walton318e5342012-11-15 02:59:30993 Object(_) | Null => true
994 }
995 }
996
997 Object(ref d0) => {
998 match *other {
999 Number(_) | String(_) | Boolean(_) | List(_) => false,
1000 Object(ref d1) => {
1001 unsafe {
1002 let mut d0_flat = ~[];
1003 let mut d1_flat = ~[];
1004
Tim Chevalier3e7da962013-01-11 04:09:161005 // FIXME #4430: this is horribly inefficient...
Daniel Micay9599cc82013-02-08 02:03:131006 for d0.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301007 d0_flat.push((@copy *k, @copy *v));
1008 }
1009 d0_flat.qsort();
1010
Daniel Micay9599cc82013-02-08 02:03:131011 for d1.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301012 d1_flat.push((@copy *k, @copy *v));
1013 }
1014 d1_flat.qsort();
1015
1016 d0_flat < d1_flat
1017 }
1018 }
1019 Null => true
1020 }
1021 }
1022
1023 Null => {
1024 match *other {
1025 Number(_) | String(_) | Boolean(_) | List(_) |
1026 Object(_) =>
1027 false,
1028 Null => true
1029 }
1030 }
1031 }
1032 }
Patrick Walton318e5342012-11-15 02:59:301033 pure fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) }
Patrick Walton318e5342012-11-15 02:59:301034 pure fn ge(&self, other: &Json) -> bool { !(*self).lt(other) }
Patrick Walton318e5342012-11-15 02:59:301035 pure fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) }
Patrick Walton22b87572012-09-08 01:53:141036}
1037
Patrick Walton9117dcb2012-09-20 01:00:261038impl Error : Eq {
Patrick Walton318e5342012-11-15 02:59:301039 pure fn eq(&self, other: &Error) -> bool {
1040 (*self).line == other.line &&
1041 (*self).col == other.col &&
1042 (*self).msg == other.msg
1043 }
Patrick Walton318e5342012-11-15 02:59:301044 pure fn ne(&self, other: &Error) -> bool { !(*self).eq(other) }
Patrick Walton9117dcb2012-09-20 01:00:261045}
Patrick Walton96534362012-08-27 23:26:351046
Ben Striegela605fd02012-08-11 14:08:421047trait ToJson { fn to_json() -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:321048
Ben Striegela605fd02012-08-11 14:08:421049impl Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421050 fn to_json() -> Json { copy self }
Erick Tryzelaared5af702012-05-28 19:10:321051}
1052
Ben Striegela605fd02012-08-11 14:08:421053impl @Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421054 fn to_json() -> Json { (*self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:541055}
1056
Ben Striegela605fd02012-08-11 14:08:421057impl int: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421058 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541059}
1060
Ben Striegela605fd02012-08-11 14:08:421061impl i8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421062 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321063}
1064
Ben Striegela605fd02012-08-11 14:08:421065impl i16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421066 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321067}
1068
Ben Striegela605fd02012-08-11 14:08:421069impl i32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421070 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321071}
1072
Ben Striegela605fd02012-08-11 14:08:421073impl i64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421074 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321075}
1076
Ben Striegela605fd02012-08-11 14:08:421077impl uint: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421078 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541079}
1080
Ben Striegela605fd02012-08-11 14:08:421081impl u8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421082 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321083}
1084
Ben Striegela605fd02012-08-11 14:08:421085impl u16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421086 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321087}
1088
Ben Striegela605fd02012-08-11 14:08:421089impl u32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421090 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321091}
1092
Ben Striegela605fd02012-08-11 14:08:421093impl u64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421094 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321095}
1096
Ben Striegela605fd02012-08-11 14:08:421097impl float: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421098 fn to_json() -> Json { Number(self) }
Erick Tryzelaared5af702012-05-28 19:10:321099}
1100
Ben Striegela605fd02012-08-11 14:08:421101impl f32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421102 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321103}
1104
Ben Striegela605fd02012-08-11 14:08:421105impl f64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421106 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321107}
1108
Ben Striegela605fd02012-08-11 14:08:421109impl (): ToJson {
1110 fn to_json() -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321111}
1112
Ben Striegela605fd02012-08-11 14:08:421113impl bool: ToJson {
1114 fn to_json() -> Json { Boolean(self) }
Erick Tryzelaared5af702012-05-28 19:10:321115}
1116
Ben Striegela605fd02012-08-11 14:08:421117impl ~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421118 fn to_json() -> Json { String(copy self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511119}
1120
Ben Striegela605fd02012-08-11 14:08:421121impl @~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421122 fn to_json() -> Json { String(copy *self) }
Erick Tryzelaared5af702012-05-28 19:10:321123}
1124
Ben Striegela605fd02012-08-11 14:08:421125impl <A: ToJson, B: ToJson> (A, B): ToJson {
1126 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081127 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181128 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421129 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561130 }
1131 }
Erick Tryzelaared5af702012-05-28 19:10:321132 }
1133}
1134
Ben Striegela605fd02012-08-11 14:08:421135impl <A: ToJson, B: ToJson, C: ToJson> (A, B, C): ToJson {
Ben Striegela605fd02012-08-11 14:08:421136 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081137 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181138 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421139 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561140 }
1141 }
Erick Tryzelaared5af702012-05-28 19:10:321142 }
1143}
1144
Ben Striegela605fd02012-08-11 14:08:421145impl <A: ToJson> ~[A]: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421146 fn to_json() -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321147}
1148
Daniel Micay7f0fa142013-01-23 22:06:321149impl <A: ToJson Copy> LinearMap<~str, A>: ToJson {
Ben Striegela605fd02012-08-11 14:08:421150 fn to_json() -> Json {
Daniel Micay7f0fa142013-01-23 22:06:321151 let mut d = LinearMap::new();
Daniel Micay9599cc82013-02-08 02:03:131152 for self.each |&(key, value)| {
Erick Tryzelaar49d00b22012-09-24 16:55:421153 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321154 }
Erick Tryzelaar49d00b22012-09-24 16:55:421155 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321156 }
1157}
1158
Ben Striegela605fd02012-08-11 14:08:421159impl <A: ToJson> Option<A>: ToJson {
1160 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081161 match self {
Ben Striegela605fd02012-08-11 14:08:421162 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181163 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321164 }
1165 }
1166}
1167
Ben Striegela605fd02012-08-11 14:08:421168impl Json: to_str::ToStr {
Erick Tryzelaar9adfa592013-02-04 04:47:261169 pure fn to_str(&self) -> ~str { to_str(self) }
Erick Tryzelaared5af702012-05-28 19:10:321170}
1171
Ben Striegela605fd02012-08-11 14:08:421172impl Error: to_str::ToStr {
Erick Tryzelaar9adfa592013-02-04 04:47:261173 pure fn to_str(&self) -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521174 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381175 }
1176}
1177
Brian Anderson6e27b272012-01-18 03:05:071178#[cfg(test)]
1179mod tests {
Patrick Walton2db3abd2013-01-09 03:37:251180 use core::prelude::*;
1181
1182 use json::*;
1183
Patrick Waltonfa5ee932012-12-28 02:24:181184 use core::result;
Daniel Micay7f0fa142013-01-23 22:06:321185 use core::hashmap::linear::LinearMap;
John Clementsf91160b2013-02-08 01:06:261186 use core::cmp;
1187
Patrick Waltonfa5ee932012-12-28 02:24:181188
Erick Tryzelaar49d00b22012-09-24 16:55:421189 fn mk_object(items: &[(~str, Json)]) -> Json {
Daniel Micaybba55202013-01-24 02:09:501190 let mut d = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:321191
Erick Tryzelaar49d00b22012-09-24 16:55:421192 for items.each |item| {
1193 match *item {
Tim Chevalier90d06b82012-09-19 05:35:421194 (copy key, copy value) => { d.insert(key, move value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421195 }
Erick Tryzelaar012dec52012-02-26 00:39:321196 };
1197
Tim Chevalier90d06b82012-09-19 05:35:421198 Object(move d)
Brian Anderson6e27b272012-01-18 03:05:071199 }
1200
1201 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321202 fn test_write_null() {
Erick Tryzelaar49d00b22012-09-24 16:55:421203 assert to_str(&Null) == ~"null";
Brian Anderson6e27b272012-01-18 03:05:071204 }
1205
1206 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421207 fn test_write_number() {
1208 assert to_str(&Number(3f)) == ~"3";
1209 assert to_str(&Number(3.1f)) == ~"3.1";
1210 assert to_str(&Number(-1.5f)) == ~"-1.5";
1211 assert to_str(&Number(0.5f)) == ~"0.5";
Brian Anderson6e27b272012-01-18 03:05:071212 }
1213
1214 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321215 fn test_write_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421216 assert to_str(&String(~"")) == ~"\"\"";
1217 assert to_str(&String(~"foo")) == ~"\"foo\"";
Brian Anderson6e27b272012-01-18 03:05:071218 }
1219
1220 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321221 fn test_write_bool() {
Erick Tryzelaar49d00b22012-09-24 16:55:421222 assert to_str(&Boolean(true)) == ~"true";
1223 assert to_str(&Boolean(false)) == ~"false";
Brian Anderson6e27b272012-01-18 03:05:071224 }
1225
1226 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321227 fn test_write_list() {
Erick Tryzelaar49d00b22012-09-24 16:55:421228 assert to_str(&List(~[])) == ~"[]";
1229 assert to_str(&List(~[Boolean(true)])) == ~"[true]";
1230 assert to_str(&List(~[
Ben Striegela605fd02012-08-11 14:08:421231 Boolean(false),
1232 Null,
Erick Tryzelaar49d00b22012-09-24 16:55:421233 List(~[String(~"foo\nbar"), Number(3.5f)])
1234 ])) == ~"[false,null,[\"foo\\nbar\",3.5]]";
Erick Tryzelaar012dec52012-02-26 00:39:321235 }
1236
1237 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421238 fn test_write_object() {
1239 assert to_str(&mk_object(~[])) == ~"{}";
1240 assert to_str(&mk_object(~[(~"a", Boolean(true))]))
1241 == ~"{\"a\":true}";
1242 let a = mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421243 (~"a", Boolean(true)),
Erick Tryzelaar49d00b22012-09-24 16:55:421244 (~"b", List(~[
1245 mk_object(~[(~"c", String(~"\x0c\r"))]),
1246 mk_object(~[(~"d", String(~""))])
Michael Sullivan98e161f2012-06-29 23:26:561247 ]))
Graydon Hoare11871b82012-08-30 23:27:151248 ]);
Erick Tryzelaar49d00b22012-09-24 16:55:421249 // We can't compare the strings directly because the object fields be
1250 // printed in a different order.
1251 let b = result::unwrap(from_str(to_str(&a)));
Graydon Hoare11871b82012-08-30 23:27:151252 assert a == b;
Erick Tryzelaar012dec52012-02-26 00:39:321253 }
1254
John Clementsf91160b2013-02-08 01:06:261255 // two fns copied from libsyntax/util/testing.rs.
1256 // Should they be in their own crate?
1257 pub pure fn check_equal_ptr<T : cmp::Eq> (given : &T, expected: &T) {
1258 if !((given == expected) && (expected == given )) {
1259 die!(fmt!("given %?, expected %?",given,expected));
1260 }
1261 }
1262
1263 pub pure fn check_equal<T : cmp::Eq> (given : T, expected: T) {
1264 if !((given == expected) && (expected == given )) {
1265 die!(fmt!("given %?, expected %?",given,expected));
1266 }
1267 }
1268
1269 // testing both auto_encode's calling patterns
1270 // and json... not sure where to put these tests.
1271 #[test]
1272 fn test_write_enum () {
1273 let bw = @io::BytesWriter {bytes: dvec::DVec(), pos: 0};
1274 let bww : @io::Writer = (bw as @io::Writer);
1275 let encoder = (@Encoder(bww) as @serialize::Encoder);
1276 do encoder.emit_enum(~"animal") {
1277 do encoder.emit_enum_variant (~"frog",37,1242) {
1278 // name of frog:
1279 do encoder.emit_enum_variant_arg (0) {
1280 encoder.emit_owned_str(~"Henry")
1281 }
1282 // mass of frog in grams:
1283 do encoder.emit_enum_variant_arg (1) {
1284 encoder.emit_int(349);
1285 }
1286 }
1287 }
1288 check_equal(str::from_bytes(bw.bytes.data),
1289 ~"[\"frog\",\"Henry\",349]");
1290 }
1291
Erick Tryzelaar012dec52012-02-26 00:39:321292 #[test]
1293 fn test_trailing_characters() {
Michael Sullivan92743dc2012-07-14 05:57:481294 assert from_str(~"nulla") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421295 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481296 assert from_str(~"truea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421297 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481298 assert from_str(~"falsea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421299 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481300 assert from_str(~"1a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421301 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481302 assert from_str(~"[]a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421303 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481304 assert from_str(~"{}a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421305 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Erick Tryzelaar012dec52012-02-26 00:39:321306 }
1307
1308 #[test]
1309 fn test_read_identifiers() {
Michael Sullivan92743dc2012-07-14 05:57:481310 assert from_str(~"n") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421311 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481312 assert from_str(~"nul") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421313 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321314
Michael Sullivan92743dc2012-07-14 05:57:481315 assert from_str(~"t") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421316 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481317 assert from_str(~"truz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421318 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321319
Michael Sullivan92743dc2012-07-14 05:57:481320 assert from_str(~"f") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421321 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481322 assert from_str(~"faz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421323 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321324
Ben Striegela605fd02012-08-11 14:08:421325 assert from_str(~"null") == Ok(Null);
1326 assert from_str(~"true") == Ok(Boolean(true));
1327 assert from_str(~"false") == Ok(Boolean(false));
1328 assert from_str(~" null ") == Ok(Null);
1329 assert from_str(~" true ") == Ok(Boolean(true));
1330 assert from_str(~" false ") == Ok(Boolean(false));
Erick Tryzelaar012dec52012-02-26 00:39:321331 }
1332
1333 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421334 fn test_read_number() {
Michael Sullivan92743dc2012-07-14 05:57:481335 assert from_str(~"+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421336 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481337 assert from_str(~".") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421338 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321339
Michael Sullivan92743dc2012-07-14 05:57:481340 assert from_str(~"-") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421341 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481342 assert from_str(~"00") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421343 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481344 assert from_str(~"1.") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421345 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481346 assert from_str(~"1e") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421347 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481348 assert from_str(~"1e+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421349 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"});
Erick Tryzelaar012dec52012-02-26 00:39:321350
Erick Tryzelaar49d00b22012-09-24 16:55:421351 assert from_str(~"3") == Ok(Number(3f));
1352 assert from_str(~"3.1") == Ok(Number(3.1f));
1353 assert from_str(~"-1.2") == Ok(Number(-1.2f));
1354 assert from_str(~"0.4") == Ok(Number(0.4f));
1355 assert from_str(~"0.4e5") == Ok(Number(0.4e5f));
1356 assert from_str(~"0.4e+15") == Ok(Number(0.4e15f));
1357 assert from_str(~"0.4e-01") == Ok(Number(0.4e-01f));
1358 assert from_str(~" 3 ") == Ok(Number(3f));
Erick Tryzelaar012dec52012-02-26 00:39:321359 }
1360
1361 #[test]
1362 fn test_read_str() {
Michael Sullivan92743dc2012-07-14 05:57:481363 assert from_str(~"\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421364 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"});
Michael Sullivan92743dc2012-07-14 05:57:481365 assert from_str(~"\"lol") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421366 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"});
Erick Tryzelaar012dec52012-02-26 00:39:321367
Erick Tryzelaar49d00b22012-09-24 16:55:421368 assert from_str(~"\"\"") == Ok(String(~""));
1369 assert from_str(~"\"foo\"") == Ok(String(~"foo"));
1370 assert from_str(~"\"\\\"\"") == Ok(String(~"\""));
1371 assert from_str(~"\"\\b\"") == Ok(String(~"\x08"));
1372 assert from_str(~"\"\\n\"") == Ok(String(~"\n"));
1373 assert from_str(~"\"\\r\"") == Ok(String(~"\r"));
1374 assert from_str(~"\"\\t\"") == Ok(String(~"\t"));
1375 assert from_str(~" \"foo\" ") == Ok(String(~"foo"));
Erick Tryzelaar012dec52012-02-26 00:39:321376 }
1377
1378 #[test]
Kevin Cantucf386182012-08-31 04:03:191379 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421380 assert from_str(~"\"\\u12ab\"") == Ok(String(~"\u12ab"));
1381 assert from_str(~"\"\\uAB12\"") == Ok(String(~"\uAB12"));
Kevin Cantucf386182012-08-31 04:03:191382 }
1383
1384 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321385 fn test_read_list() {
Michael Sullivan92743dc2012-07-14 05:57:481386 assert from_str(~"[") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421387 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481388 assert from_str(~"[1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421389 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"});
Michael Sullivan92743dc2012-07-14 05:57:481390 assert from_str(~"[1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421391 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481392 assert from_str(~"[1,]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421393 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481394 assert from_str(~"[6 7]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421395 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"});
Erick Tryzelaar012dec52012-02-26 00:39:321396
Erick Tryzelaar49d00b22012-09-24 16:55:421397 assert from_str(~"[]") == Ok(List(~[]));
1398 assert from_str(~"[ ]") == Ok(List(~[]));
1399 assert from_str(~"[true]") == Ok(List(~[Boolean(true)]));
1400 assert from_str(~"[ false ]") == Ok(List(~[Boolean(false)]));
1401 assert from_str(~"[null]") == Ok(List(~[Null]));
1402 assert from_str(~"[3, 1]") == Ok(List(~[Number(3f), Number(1f)]));
1403 assert from_str(~"\n[3, 2]\n") == Ok(List(~[Number(3f), Number(2f)]));
Michael Sullivan92743dc2012-07-14 05:57:481404 assert from_str(~"[2, [4, 1]]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421405 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])]));
Erick Tryzelaar012dec52012-02-26 00:39:321406 }
1407
1408 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421409 fn test_read_object() {
Michael Sullivan92743dc2012-07-14 05:57:481410 assert from_str(~"{") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421411 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481412 assert from_str(~"{ ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421413 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481414 assert from_str(~"{1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421415 Err(Error {line: 1u, col: 2u, msg: @~"key must be a string"});
Michael Sullivan92743dc2012-07-14 05:57:481416 assert from_str(~"{ \"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421417 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481418 assert from_str(~"{\"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421419 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481420 assert from_str(~"{\"a\" ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421421 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321422
Michael Sullivan92743dc2012-07-14 05:57:481423 assert from_str(~"{\"a\" 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421424 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"});
Michael Sullivan92743dc2012-07-14 05:57:481425 assert from_str(~"{\"a\":") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421426 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481427 assert from_str(~"{\"a\":1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421428 Err(Error {line: 1u, col: 7u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481429 assert from_str(~"{\"a\":1 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421430 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"});
Michael Sullivan92743dc2012-07-14 05:57:481431 assert from_str(~"{\"a\":1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421432 Err(Error {line: 1u, col: 8u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321433
Erick Tryzelaar49d00b22012-09-24 16:55:421434 assert result::unwrap(from_str(~"{}")) == mk_object(~[]);
1435 assert result::unwrap(from_str(~"{\"a\": 3}")) ==
1436 mk_object(~[(~"a", Number(3.0f))]);
Erick Tryzelaar012dec52012-02-26 00:39:321437
Erick Tryzelaar49d00b22012-09-24 16:55:421438 assert result::unwrap(from_str(~"{ \"a\": null, \"b\" : true }")) ==
1439 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421440 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421441 (~"b", Boolean(true))]);
1442 assert result::unwrap(
1443 from_str(~"\n{ \"a\": null, \"b\" : true }\n")) ==
1444 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421445 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421446 (~"b", Boolean(true))]);
1447 assert result::unwrap(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")) ==
1448 mk_object(~[
1449 (~"a", Number(1.0)),
1450 (~"b", List(~[Boolean(true)]))
1451 ]);
1452 assert result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481453 ~"{" +
1454 ~"\"a\": 1.0, " +
1455 ~"\"b\": [" +
1456 ~"true," +
1457 ~"\"foo\\nbar\", " +
1458 ~"{ \"c\": {\"d\": null} } " +
1459 ~"]" +
Erick Tryzelaar49d00b22012-09-24 16:55:421460 ~"}")) ==
1461 mk_object(~[
1462 (~"a", Number(1.0f)),
1463 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421464 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421465 String(~"foo\nbar"),
1466 mk_object(~[
1467 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561468 ])
1469 ]))
Erick Tryzelaar49d00b22012-09-24 16:55:421470 ]);
Erick Tryzelaar012dec52012-02-26 00:39:321471 }
1472
1473 #[test]
1474 fn test_multiline_errors() {
Michael Sullivan92743dc2012-07-14 05:57:481475 assert from_str(~"{\n \"foo\":\n \"bar\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421476 Err(Error {line: 3u, col: 8u, msg: @~"EOF while parsing object"});
Brian Anderson6e27b272012-01-18 03:05:071477 }
1478}