blob: 4ebd151eb2e03cce107fcd891fa98615c939abeb [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
Patrick Walton07c3f5c2013-02-27 01:12:0085impl serialize::Encoder for 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 Clementsc952c042013-02-08 23:36:40129 // encoding of enums is special-cased for Option. Specifically:
130 // Some(34) => 34
131 // None => null
132
133 // other enums are encoded as vectors:
134 // Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
John Clements7736ed62013-02-09 02:58:33135
John Clementsc952c042013-02-08 23:36:40136 // the default expansion for enums is more verbose than I'd like;
137 // specifically, the inner pair of brackets seems superfluous,
138 // BUT the design of the enumeration framework and the requirements
139 // of the special-case for Option mean that a first argument must
140 // be encoded "naked"--with no commas--and that the option name
141 // can't be followed by just a comma, because there might not
142 // be any elements in the tuple.
John Clements7736ed62013-02-09 02:58:33143
John Clementsc05954a2013-02-10 19:25:46144 // FIXME #4872: this would be more precise and less frightening
John Clementsc952c042013-02-08 23:36:40145 // with fully-qualified option names. To get that information,
John Clements7736ed62013-02-09 02:58:33146 // we'd have to change the expansion of auto-encode to pass
147 // those along.
John Clementsc952c042013-02-08 23:36:40148
149 if (name == ~"Some") {
150 f();
151 } else if (name == ~"None") {
152 self.wr.write_str(~"null");
153 } else {
154 self.wr.write_char('[');
155 self.wr.write_str(escape_str(name));
156 self.wr.write_char(',');
157 self.wr.write_char('[');
158 f();
159 self.wr.write_char(']');
160 self.wr.write_char(']');
161 }
Erick Tryzelaar49d00b22012-09-24 16:55:42162 }
John Clementsf91160b2013-02-08 01:06:26163
John Clementsc952c042013-02-08 23:36:40164 fn emit_enum_variant_arg(&self, idx: uint, f: fn()) {
165 if (idx != 0) {self.wr.write_char(',');}
John Clementsfe823742013-02-07 01:19:11166 f();
Erick Tryzelaar49d00b22012-09-24 16:55:42167 }
168
Erick Tryzelaar81423a32012-09-27 04:35:13169 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42170 self.wr.write_char('[');
171 f();
172 self.wr.write_char(']');
173 }
John Clements7736ed62013-02-09 02:58:33174
Erick Tryzelaar81423a32012-09-27 04:35:13175 fn emit_owned_vec(&self, len: uint, f: fn()) {
176 self.emit_borrowed_vec(len, f)
177 }
178 fn emit_managed_vec(&self, len: uint, f: fn()) {
179 self.emit_borrowed_vec(len, f)
180 }
Erick Tryzelaar49d00b22012-09-24 16:55:42181 fn emit_vec_elt(&self, idx: uint, f: fn()) {
182 if idx != 0 { self.wr.write_char(','); }
183 f()
184 }
185
Erick Tryzelaar49d00b22012-09-24 16:55:42186 fn emit_rec(&self, f: fn()) {
187 self.wr.write_char('{');
188 f();
189 self.wr.write_char('}');
190 }
Michael Neumann2b6c4562012-12-27 12:16:16191 fn emit_struct(&self, _name: &str, _len: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13192 self.wr.write_char('{');
193 f();
194 self.wr.write_char('}');
195 }
196 fn emit_field(&self, name: &str, idx: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42197 if idx != 0 { self.wr.write_char(','); }
198 self.wr.write_str(escape_str(name));
199 self.wr.write_char(':');
200 f();
201 }
Erick Tryzelaar81423a32012-09-27 04:35:13202
203 fn emit_tup(&self, len: uint, f: fn()) {
204 self.emit_borrowed_vec(len, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42205 }
206 fn emit_tup_elt(&self, idx: uint, f: fn()) {
207 self.emit_vec_elt(idx, f)
208 }
209}
210
Erick Tryzelaar8650c6f2012-12-18 03:31:04211pub struct PrettyEncoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42212 priv wr: io::Writer,
213 priv mut indent: uint,
214}
215
Erick Tryzelaar8650c6f2012-12-18 03:31:04216pub fn PrettyEncoder(wr: io::Writer) -> PrettyEncoder {
217 PrettyEncoder { wr: wr, indent: 0 }
Erick Tryzelaar49d00b22012-09-24 16:55:42218}
219
Patrick Walton07c3f5c2013-02-27 01:12:00220impl serialize::Encoder for PrettyEncoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42221 fn emit_nil(&self) { self.wr.write_str("null") }
222
223 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
224 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
225 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
226 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
227 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
228
229 fn emit_int(&self, v: int) { self.emit_float(v as float); }
230 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
231 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
232 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
233 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
234
235 fn emit_bool(&self, v: bool) {
236 if v {
237 self.wr.write_str("true");
238 } else {
239 self.wr.write_str("false");
240 }
241 }
242
243 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
244 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
245 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39246 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42247 }
248
Erick Tryzelaar81423a32012-09-27 04:35:13249 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
250
251 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
252 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
253 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
254
255 fn emit_borrowed(&self, f: fn()) { f() }
256 fn emit_owned(&self, f: fn()) { f() }
257 fn emit_managed(&self, f: fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42258
259 fn emit_enum(&self, name: &str, f: fn()) {
Nick Desaulniers4445b382013-02-12 03:26:38260 if name != "option" { fail!(~"only supports option enum") }
Erick Tryzelaar49d00b22012-09-24 16:55:42261 f()
262 }
263 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
264 if id == 0 {
265 self.emit_nil();
266 } else {
267 f()
268 }
269 }
270 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
271 f()
272 }
273
Erick Tryzelaar81423a32012-09-27 04:35:13274 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42275 self.wr.write_char('[');
276 self.indent += 2;
277 f();
278 self.indent -= 2;
279 self.wr.write_char(']');
280 }
Erick Tryzelaar81423a32012-09-27 04:35:13281 fn emit_owned_vec(&self, len: uint, f: fn()) {
282 self.emit_borrowed_vec(len, f)
283 }
284 fn emit_managed_vec(&self, len: uint, f: fn()) {
285 self.emit_borrowed_vec(len, f)
286 }
Erick Tryzelaar49d00b22012-09-24 16:55:42287 fn emit_vec_elt(&self, idx: uint, f: fn()) {
288 if idx == 0 {
289 self.wr.write_char('\n');
290 } else {
291 self.wr.write_str(",\n");
292 }
293 self.wr.write_str(spaces(self.indent));
294 f()
295 }
296
Erick Tryzelaar49d00b22012-09-24 16:55:42297 fn emit_rec(&self, f: fn()) {
298 self.wr.write_char('{');
299 self.indent += 2;
300 f();
301 self.indent -= 2;
302 self.wr.write_char('}');
303 }
Michael Neumann2b6c4562012-12-27 12:16:16304 fn emit_struct(&self, _name: &str, _len: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13305 self.emit_rec(f)
306 }
307 fn emit_field(&self, name: &str, idx: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42308 if idx == 0 {
309 self.wr.write_char('\n');
310 } else {
311 self.wr.write_str(",\n");
312 }
313 self.wr.write_str(spaces(self.indent));
314 self.wr.write_str(escape_str(name));
315 self.wr.write_str(": ");
316 f();
317 }
318 fn emit_tup(&self, sz: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13319 self.emit_borrowed_vec(sz, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42320 }
321 fn emit_tup_elt(&self, idx: uint, f: fn()) {
322 self.emit_vec_elt(idx, f)
323 }
324}
325
Patrick Walton07c3f5c2013-02-27 01:12:00326impl<S:serialize::Encoder> serialize::Encodable<S> for Json {
Erick Tryzelaar8650c6f2012-12-18 03:31:04327 fn encode(&self, s: &S) {
Erick Tryzelaarab89b5c2012-10-13 16:11:33328 match *self {
Erick Tryzelaar8650c6f2012-12-18 03:31:04329 Number(v) => v.encode(s),
330 String(ref v) => v.encode(s),
331 Boolean(v) => v.encode(s),
332 List(ref v) => v.encode(s),
Erick Tryzelaarab89b5c2012-10-13 16:11:33333 Object(ref v) => {
334 do s.emit_rec || {
335 let mut idx = 0;
Daniel Micay9599cc82013-02-08 02:03:13336 for v.each |&(key, value)| {
Erick Tryzelaarab89b5c2012-10-13 16:11:33337 do s.emit_field(*key, idx) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04338 value.encode(s);
Erick Tryzelaarab89b5c2012-10-13 16:11:33339 }
340 idx += 1;
341 }
342 }
343 },
344 Null => s.emit_nil(),
345 }
346 }
347}
348
Erick Tryzelaar8650c6f2012-12-18 03:31:04349/// Encodes a json value into a io::writer
Erick Tryzelaar49d00b22012-09-24 16:55:42350pub fn to_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04351 json.encode(&Encoder(wr))
Erick Tryzelaar49d00b22012-09-24 16:55:42352}
353
Erick Tryzelaar8650c6f2012-12-18 03:31:04354/// Encodes a json value into a string
Patrick Walton54b2cad2013-01-23 19:43:58355pub pure fn to_str(json: &Json) -> ~str {
356 unsafe {
357 // ugh, should be safe
358 io::with_str_writer(|wr| to_writer(wr, json))
359 }
Elly Jonesbd726262011-11-07 19:01:28360}
361
Erick Tryzelaar8650c6f2012-12-18 03:31:04362/// Encodes a json value into a io::writer
Erick Tryzelaar49d00b22012-09-24 16:55:42363pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04364 json.encode(&PrettyEncoder(wr))
Kevin Cantud47cb102012-08-30 23:39:56365}
366
Erick Tryzelaar8650c6f2012-12-18 03:31:04367/// Encodes a json value into a string
Erick Tryzelaar49d00b22012-09-24 16:55:42368pub fn to_pretty_str(json: &Json) -> ~str {
369 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40370}
371
Erick Tryzelaar49d00b22012-09-24 16:55:42372pub struct Parser {
373 priv rdr: io::Reader,
374 priv mut ch: char,
375 priv mut line: uint,
376 priv mut col: uint,
377}
378
Erick Tryzelaar8650c6f2012-12-18 03:31:04379/// Decode a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42380pub fn Parser(rdr: io::Reader) -> Parser {
381 Parser {
382 rdr: rdr,
383 ch: rdr.read_char(),
Tim Chevalier90d06b82012-09-19 05:35:42384 line: 1,
385 col: 1,
Erick Tryzelaar49d00b22012-09-24 16:55:42386 }
387}
388
389pub impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09390 fn parse(&self) -> Result<Json, Error> {
Luqman Aden4cf51c22013-02-15 07:30:30391 match self.parse_value() {
392 Ok(value) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42393 // Skip trailing whitespaces.
394 self.parse_whitespace();
395 // Make sure there is no trailing characters.
396 if self.eof() {
Luqman Aden4cf51c22013-02-15 07:30:30397 Ok(value)
Erick Tryzelaar49d00b22012-09-24 16:55:42398 } else {
399 self.error(~"trailing characters")
400 }
401 }
Luqman Aden4cf51c22013-02-15 07:30:30402 Err(e) => Err(e)
Erick Tryzelaar49d00b22012-09-24 16:55:42403 }
404 }
405}
406
407priv impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09408 fn eof(&self) -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28409
Ben Striegel0fed29c2013-03-08 02:11:09410 fn bump(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32411 self.ch = self.rdr.read_char();
412
413 if self.ch == '\n' {
414 self.line += 1u;
415 self.col = 1u;
416 } else {
417 self.col += 1u;
418 }
Elly Jonesbd726262011-11-07 19:01:28419 }
420
Ben Striegel0fed29c2013-03-08 02:11:09421 fn next_char(&self) -> char {
Erick Tryzelaar012dec52012-02-26 00:39:32422 self.bump();
423 self.ch
Elly Jonesbd726262011-11-07 19:01:28424 }
425
Ben Striegel0fed29c2013-03-08 02:11:09426 fn error<T>(&self, msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42427 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28428 }
Elly Jonesbd726262011-11-07 19:01:28429
Ben Striegel0fed29c2013-03-08 02:11:09430 fn parse_value(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32431 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28432
Brian Andersonb3559362012-08-02 00:30:05433 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32434
Brian Andersonecaf9e32012-08-06 19:34:08435 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42436 'n' => self.parse_ident(~"ull", Null),
437 't' => self.parse_ident(~"rue", Boolean(true)),
438 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05439 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42440 '"' =>
Luqman Aden4cf51c22013-02-15 07:30:30441 match self.parse_str() {
442 Ok(s) => Ok(String(s)),
443 Err(e) => Err(e),
Erick Tryzelaar49d00b22012-09-24 16:55:42444 },
Brian Anderson025d8662012-08-04 02:59:04445 '[' => self.parse_list(),
446 '{' => self.parse_object(),
447 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32448 }
449 }
450
Ben Striegel0fed29c2013-03-08 02:11:09451 fn parse_whitespace(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32452 while char::is_whitespace(self.ch) { self.bump(); }
453 }
454
Ben Striegel0fed29c2013-03-08 02:11:09455 fn parse_ident(&self, ident: &str, value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07456 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32457 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30458 Ok(value)
Erick Tryzelaar012dec52012-02-26 00:39:32459 } else {
Michael Sullivan92743dc2012-07-14 05:57:48460 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32461 }
462 }
463
Ben Striegel0fed29c2013-03-08 02:11:09464 fn parse_number(&self) -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56465 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32466
467 if self.ch == '-' {
468 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00469 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28470 }
Elly Jonesbd726262011-11-07 19:01:28471
Brian Andersonecaf9e32012-08-06 19:34:08472 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31473 Ok(res) => res,
474 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32475 };
476
477 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08478 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31479 Ok(r) => res = r,
480 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28481 }
Elly Jonesbd726262011-11-07 19:01:28482 }
Erick Tryzelaar012dec52012-02-26 00:39:32483
484 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08485 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31486 Ok(r) => res = r,
487 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32488 }
489 }
490
Erick Tryzelaar49d00b22012-09-24 16:55:42491 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28492 }
493
Ben Striegel0fed29c2013-03-08 02:11:09494 fn parse_integer(&self) -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56495 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32496
Brian Andersonecaf9e32012-08-06 19:34:08497 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04498 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32499 self.bump();
500
501 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08502 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05503 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04504 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32505 }
506 }
Brian Anderson80c4f742012-09-02 01:38:05507 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32508 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08509 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05510 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32511 res *= 10f;
512 res += ((self.ch as int) - ('0' as int)) as float;
513
514 self.bump();
515 }
Brian Anderson025d8662012-08-04 02:59:04516 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32517 }
518 }
519 }
Brian Anderson025d8662012-08-04 02:59:04520 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32521 }
522
Brian Anderson0c6e4702012-08-26 23:54:31523 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28524 }
525
Ben Striegel0fed29c2013-03-08 02:11:09526 fn parse_decimal(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32527 self.bump();
528
529 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08530 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05531 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04532 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32533 }
534
Niko Matsakis6b358752012-03-14 18:03:56535 let mut res = res;
536 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32537 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08538 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05539 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00540 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32541 res += (((self.ch as int) - ('0' as int)) as float) * dec;
542
543 self.bump();
544 }
Brian Anderson025d8662012-08-04 02:59:04545 _ => break
Elly Jonesbd726262011-11-07 19:01:28546 }
Elly Jonesbd726262011-11-07 19:01:28547 }
Elly Jonesbd726262011-11-07 19:01:28548
Brian Anderson0c6e4702012-08-26 23:54:31549 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32550 }
551
Ben Striegel0fed29c2013-03-08 02:11:09552 fn parse_exponent(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32553 self.bump();
554
Niko Matsakis6b358752012-03-14 18:03:56555 let mut res = res;
556 let mut exp = 0u;
557 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32558
Brian Andersonecaf9e32012-08-06 19:34:08559 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04560 '+' => self.bump(),
561 '-' => { self.bump(); neg_exp = true; }
562 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32563 }
564
565 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08566 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05567 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04568 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32569 }
570
571 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08572 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05573 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32574 exp *= 10u;
575 exp += (self.ch as uint) - ('0' as uint);
576
577 self.bump();
578 }
Brian Anderson025d8662012-08-04 02:59:04579 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32580 }
581 }
582
583 let exp = float::pow_with_uint(10u, exp);
584 if neg_exp {
585 res /= exp;
586 } else {
587 res *= exp;
588 }
589
Brian Anderson0c6e4702012-08-26 23:54:31590 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32591 }
592
Ben Striegel0fed29c2013-03-08 02:11:09593 fn parse_str(&self) -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56594 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48595 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32596
597 while !self.eof() {
598 self.bump();
599
600 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08601 match self.ch {
Tim Chevalier5a8ba072012-10-11 21:12:50602 '"' => str::push_char(&mut res, '"'),
603 '\\' => str::push_char(&mut res, '\\'),
604 '/' => str::push_char(&mut res, '/'),
605 'b' => str::push_char(&mut res, '\x08'),
606 'f' => str::push_char(&mut res, '\x0c'),
607 'n' => str::push_char(&mut res, '\n'),
608 'r' => str::push_char(&mut res, '\r'),
609 't' => str::push_char(&mut res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04610 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32611 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56612 let mut i = 0u;
613 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32614 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08615 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05616 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10617 n = n * 16u + (self.ch as uint)
618 - ('0' as uint);
619 },
620 'a' | 'A' => n = n * 16u + 10u,
621 'b' | 'B' => n = n * 16u + 11u,
622 'c' | 'C' => n = n * 16u + 12u,
623 'd' | 'D' => n = n * 16u + 13u,
624 'e' | 'E' => n = n * 16u + 14u,
625 'f' | 'F' => n = n * 16u + 15u,
626 _ => return self.error(
627 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32628 }
Niko Matsakis6b358752012-03-14 18:03:56629 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32630 }
631
632 // Error out if we didn't parse 4 digits.
633 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10634 return self.error(
635 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32636 }
637
Tim Chevalier5a8ba072012-10-11 21:12:50638 str::push_char(&mut res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32639 }
Brian Anderson025d8662012-08-04 02:59:04640 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32641 }
642 escape = false;
643 } else if self.ch == '\\' {
644 escape = true;
645 } else {
646 if self.ch == '"' {
647 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42648 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32649 }
Tim Chevalier5a8ba072012-10-11 21:12:50650 str::push_char(&mut res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32651 }
652 }
653
Michael Sullivan92743dc2012-07-14 05:57:48654 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32655 }
656
Ben Striegel0fed29c2013-03-08 02:11:09657 fn parse_list(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32658 self.bump();
659 self.parse_whitespace();
660
Michael Sullivan98e161f2012-06-29 23:26:56661 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32662
663 if self.ch == ']' {
664 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30665 return Ok(List(values));
Erick Tryzelaar012dec52012-02-26 00:39:32666 }
667
Tim Chevalier35400e12012-03-11 04:34:17668 loop {
Luqman Aden4cf51c22013-02-15 07:30:30669 match self.parse_value() {
670 Ok(v) => values.push(v),
671 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32672 }
673
674 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17675 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05676 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17677 }
Erick Tryzelaar012dec52012-02-26 00:39:32678
Brian Andersonecaf9e32012-08-06 19:34:08679 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04680 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30681 ']' => { self.bump(); return Ok(List(values)); }
Brian Anderson025d8662012-08-04 02:59:04682 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32683 }
Tim Chevalier35400e12012-03-11 04:34:17684 };
Erick Tryzelaar012dec52012-02-26 00:39:32685 }
686
Ben Striegel0fed29c2013-03-08 02:11:09687 fn parse_object(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32688 self.bump();
689 self.parse_whitespace();
690
Daniel Micay7f0fa142013-01-23 22:06:32691 let mut values = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:32692
693 if self.ch == '}' {
694 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30695 return Ok(Object(values));
Erick Tryzelaar012dec52012-02-26 00:39:32696 }
697
698 while !self.eof() {
699 self.parse_whitespace();
700
701 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05702 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32703 }
704
Luqman Aden4cf51c22013-02-15 07:30:30705 let key = match self.parse_str() {
706 Ok(key) => key,
707 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32708 };
709
710 self.parse_whitespace();
711
712 if self.ch != ':' {
713 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05714 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32715 }
716 self.bump();
717
Luqman Aden4cf51c22013-02-15 07:30:30718 match self.parse_value() {
719 Ok(value) => { values.insert(key, value); }
720 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32721 }
722 self.parse_whitespace();
723
Brian Andersonecaf9e32012-08-06 19:34:08724 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04725 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30726 '}' => { self.bump(); return Ok(Object(values)); }
Brian Anderson025d8662012-08-04 02:59:04727 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32728 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05729 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32730 }
731 }
732 }
733
Brian Andersonb3559362012-08-02 00:30:05734 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28735 }
736}
737
Erick Tryzelaar8650c6f2012-12-18 03:31:04738/// Decodes a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42739pub fn from_reader(rdr: io::Reader) -> Result<Json, Error> {
740 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28741}
742
Erick Tryzelaar8650c6f2012-12-18 03:31:04743/// Decodes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42744pub fn from_str(s: &str) -> Result<Json, Error> {
745 do io::with_str_reader(s) |rdr| {
746 from_reader(rdr)
747 }
Erick Tryzelaar012dec52012-02-26 00:39:32748}
749
Erick Tryzelaar8650c6f2012-12-18 03:31:04750pub struct Decoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42751 priv json: Json,
Niko Matsakis3168fe02013-02-26 19:34:00752 priv mut stack: ~[&self/Json],
Erick Tryzelaar49d00b22012-09-24 16:55:42753}
754
Erick Tryzelaar8650c6f2012-12-18 03:31:04755pub fn Decoder(json: Json) -> Decoder {
Luqman Aden4cf51c22013-02-15 07:30:30756 Decoder { json: json, stack: ~[] }
Elly Jonesbd726262011-11-07 19:01:28757}
Brian Anderson6e27b272012-01-18 03:05:07758
Niko Matsakis3168fe02013-02-26 19:34:00759priv impl Decoder/&self {
Niko Matsakis67a8e712012-09-27 00:33:34760 fn peek(&self) -> &self/Json {
761 if self.stack.len() == 0 { self.stack.push(&self.json); }
Erick Tryzelaar743cfce2013-03-06 03:39:18762 self.stack[self.stack.len() - 1]
Erick Tryzelaar49d00b22012-09-24 16:55:42763 }
764
Niko Matsakis67a8e712012-09-27 00:33:34765 fn pop(&self) -> &self/Json {
766 if self.stack.len() == 0 { self.stack.push(&self.json); }
Niko Matsakis21519bc2012-09-28 05:20:47767 self.stack.pop()
Erick Tryzelaar49d00b22012-09-24 16:55:42768 }
769}
770
Niko Matsakis3168fe02013-02-26 19:34:00771impl serialize::Decoder for Decoder/&self {
Erick Tryzelaar49d00b22012-09-24 16:55:42772 fn read_nil(&self) -> () {
773 debug!("read_nil");
774 match *self.pop() {
775 Null => (),
Nick Desaulniers4445b382013-02-12 03:26:38776 _ => fail!(~"not a null")
Erick Tryzelaar49d00b22012-09-24 16:55:42777 }
778 }
779
780 fn read_u64(&self) -> u64 { self.read_float() as u64 }
781 fn read_u32(&self) -> u32 { self.read_float() as u32 }
782 fn read_u16(&self) -> u16 { self.read_float() as u16 }
783 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
784 fn read_uint(&self) -> uint { self.read_float() as uint }
785
786 fn read_i64(&self) -> i64 { self.read_float() as i64 }
787 fn read_i32(&self) -> i32 { self.read_float() as i32 }
788 fn read_i16(&self) -> i16 { self.read_float() as i16 }
789 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
790 fn read_int(&self) -> int { self.read_float() as int }
791
792 fn read_bool(&self) -> bool {
793 debug!("read_bool");
794 match *self.pop() {
795 Boolean(b) => b,
Nick Desaulniers4445b382013-02-12 03:26:38796 _ => fail!(~"not a boolean")
Erick Tryzelaar49d00b22012-09-24 16:55:42797 }
798 }
799
800 fn read_f64(&self) -> f64 { self.read_float() as f64 }
801 fn read_f32(&self) -> f32 { self.read_float() as f32 }
802 fn read_float(&self) -> float {
803 debug!("read_float");
804 match *self.pop() {
805 Number(f) => f,
Nick Desaulniers4445b382013-02-12 03:26:38806 _ => fail!(~"not a number")
Erick Tryzelaar49d00b22012-09-24 16:55:42807 }
808 }
809
Erick Tryzelaar81423a32012-09-27 04:35:13810 fn read_char(&self) -> char {
811 let v = str::chars(self.read_owned_str());
Nick Desaulniers4445b382013-02-12 03:26:38812 if v.len() != 1 { fail!(~"string must have one character") }
Erick Tryzelaar81423a32012-09-27 04:35:13813 v[0]
814 }
815
816 fn read_owned_str(&self) -> ~str {
817 debug!("read_owned_str");
Erick Tryzelaar49d00b22012-09-24 16:55:42818 match *self.pop() {
819 String(ref s) => copy *s,
Nick Desaulniers4445b382013-02-12 03:26:38820 _ => fail!(~"not a string")
Erick Tryzelaar49d00b22012-09-24 16:55:42821 }
822 }
823
Erick Tryzelaar81423a32012-09-27 04:35:13824 fn read_managed_str(&self) -> @str {
Huon Wilson76dc7812012-12-10 02:29:33825 debug!("read_managed_str");
826 match *self.pop() {
827 String(ref s) => s.to_managed(),
Nick Desaulniers4445b382013-02-12 03:26:38828 _ => fail!(~"not a string")
Huon Wilson76dc7812012-12-10 02:29:33829 }
Erick Tryzelaar81423a32012-09-27 04:35:13830 }
831
832 fn read_owned<T>(&self, f: fn() -> T) -> T {
833 debug!("read_owned()");
834 f()
835 }
836
837 fn read_managed<T>(&self, f: fn() -> T) -> T {
838 debug!("read_managed()");
839 f()
840 }
841
Tim Chevalier9ff95e22012-10-01 19:36:06842 fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42843 debug!("read_enum(%s)", name);
Nick Desaulniers4445b382013-02-12 03:26:38844 if name != ~"option" { fail!(~"only supports the option enum") }
Erick Tryzelaar49d00b22012-09-24 16:55:42845 f()
846 }
847
848 fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
849 debug!("read_enum_variant()");
850 let idx = match *self.peek() {
851 Null => 0,
852 _ => 1,
853 };
854 f(idx)
855 }
856
857 fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
858 debug!("read_enum_variant_arg(idx=%u)", idx);
Nick Desaulniers4445b382013-02-12 03:26:38859 if idx != 0 { fail!(~"unknown index") }
Erick Tryzelaar49d00b22012-09-24 16:55:42860 f()
861 }
862
Erick Tryzelaar81423a32012-09-27 04:35:13863 fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
864 debug!("read_owned_vec()");
865 let len = match *self.peek() {
Niko Matsakisa380df82013-02-08 03:33:12866 List(ref list) => list.len(),
Nick Desaulniers4445b382013-02-12 03:26:38867 _ => fail!(~"not a list"),
Erick Tryzelaar81423a32012-09-27 04:35:13868 };
869 let res = f(len);
870 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30871 res
Erick Tryzelaar81423a32012-09-27 04:35:13872 }
873
874 fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
875 debug!("read_owned_vec()");
Erick Tryzelaar49d00b22012-09-24 16:55:42876 let len = match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34877 List(ref list) => list.len(),
Nick Desaulniers4445b382013-02-12 03:26:38878 _ => fail!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42879 };
880 let res = f(len);
881 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30882 res
Erick Tryzelaar49d00b22012-09-24 16:55:42883 }
884
885 fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
886 debug!("read_vec_elt(idx=%u)", idx);
887 match *self.peek() {
888 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34889 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42890 f()
891 }
Nick Desaulniers4445b382013-02-12 03:26:38892 _ => fail!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42893 }
894 }
895
Erick Tryzelaar49d00b22012-09-24 16:55:42896 fn read_rec<T>(&self, f: fn() -> T) -> T {
897 debug!("read_rec()");
898 let value = f();
899 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30900 value
Erick Tryzelaar49d00b22012-09-24 16:55:42901 }
902
Michael Neumann2b6c4562012-12-27 12:16:16903 fn read_struct<T>(&self, _name: &str, _len: uint, f: fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13904 debug!("read_struct()");
905 let value = f();
906 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30907 value
Erick Tryzelaar81423a32012-09-27 04:35:13908 }
909
910 fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
911 debug!("read_rec_field(%s, idx=%u)", name, idx);
Erick Tryzelaar49d00b22012-09-24 16:55:42912 let top = self.peek();
913 match *top {
914 Object(ref obj) => {
Daniel Micayee0a8c62013-01-23 16:47:43915 match obj.find(&name.to_owned()) {
Nick Desaulniers4445b382013-02-12 03:26:38916 None => fail!(fmt!("no such field: %s", name)),
Erick Tryzelaar49d00b22012-09-24 16:55:42917 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34918 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42919 f()
920 }
921 }
922 }
Nick Desaulniers4445b382013-02-12 03:26:38923 Number(_) => fail!(~"num"),
924 String(_) => fail!(~"str"),
925 Boolean(_) => fail!(~"bool"),
926 List(_) => fail!(fmt!("list: %?", top)),
927 Null => fail!(~"null"),
Erick Tryzelaar49d00b22012-09-24 16:55:42928
Nick Desaulniers4445b382013-02-12 03:26:38929 //_ => fail!(fmt!("not an object: %?", *top))
Erick Tryzelaar49d00b22012-09-24 16:55:42930 }
931 }
932
Erick Tryzelaar81423a32012-09-27 04:35:13933 fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
934 debug!("read_tup(len=%u)", len);
Erick Tryzelaar49d00b22012-09-24 16:55:42935 let value = f();
936 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30937 value
Erick Tryzelaar49d00b22012-09-24 16:55:42938 }
939
940 fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
941 debug!("read_tup_elt(idx=%u)", idx);
942 match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34943 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34944 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42945 f()
946 }
Nick Desaulniers4445b382013-02-12 03:26:38947 _ => fail!(~"not a list")
Erick Tryzelaar49d00b22012-09-24 16:55:42948 }
949 }
950}
951
Patrick Walton91436882013-02-14 19:47:00952impl Eq for Json {
Patrick Walton318e5342012-11-15 02:59:30953 pure fn eq(&self, other: &Json) -> bool {
Tim Chevalier3e7da962013-01-11 04:09:16954 match (self) {
955 &Number(f0) =>
956 match other { &Number(f1) => f0 == f1, _ => false },
957 &String(ref s0) =>
958 match other { &String(ref s1) => s0 == s1, _ => false },
959 &Boolean(b0) =>
960 match other { &Boolean(b1) => b0 == b1, _ => false },
961 &Null =>
962 match other { &Null => true, _ => false },
963 &List(ref v0) =>
964 match other { &List(ref v1) => v0 == v1, _ => false },
965 &Object(ref d0) => {
966 match other {
967 &Object(ref d1) => {
Patrick Walton318e5342012-11-15 02:59:30968 if d0.len() == d1.len() {
969 let mut equal = true;
Daniel Micay9599cc82013-02-08 02:03:13970 for d0.each |&(k, v0)| {
Daniel Micayee0a8c62013-01-23 16:47:43971 match d1.find(k) {
Patrick Walton318e5342012-11-15 02:59:30972 Some(v1) if v0 == v1 => { },
973 _ => { equal = false; break }
974 }
975 };
976 equal
977 } else {
978 false
979 }
980 }
981 _ => false
982 }
983 }
984 }
985 }
Tim Chevalier3e7da962013-01-11 04:09:16986 pure fn ne(&self, other: &Json) -> bool { !self.eq(other) }
Erick Tryzelaar49d00b22012-09-24 16:55:42987}
988
Patrick Walton22b87572012-09-08 01:53:14989/// Test if two json values are less than one another
Patrick Walton91436882013-02-14 19:47:00990impl Ord for Json {
Patrick Walton318e5342012-11-15 02:59:30991 pure fn lt(&self, other: &Json) -> bool {
992 match (*self) {
993 Number(f0) => {
994 match *other {
995 Number(f1) => f0 < f1,
996 String(_) | Boolean(_) | List(_) | Object(_) |
997 Null => true
998 }
999 }
1000
1001 String(ref s0) => {
1002 match *other {
1003 Number(_) => false,
1004 String(ref s1) => s0 < s1,
1005 Boolean(_) | List(_) | Object(_) | Null => true
1006 }
1007 }
1008
1009 Boolean(b0) => {
1010 match *other {
1011 Number(_) | String(_) => false,
1012 Boolean(b1) => b0 < b1,
1013 List(_) | Object(_) | Null => true
1014 }
1015 }
1016
Patrick Walton98fdcb02012-12-08 03:34:571017 List(ref l0) => {
Patrick Walton318e5342012-11-15 02:59:301018 match *other {
1019 Number(_) | String(_) | Boolean(_) => false,
Patrick Walton98fdcb02012-12-08 03:34:571020 List(ref l1) => (*l0) < (*l1),
Patrick Walton318e5342012-11-15 02:59:301021 Object(_) | Null => true
1022 }
1023 }
1024
1025 Object(ref d0) => {
1026 match *other {
1027 Number(_) | String(_) | Boolean(_) | List(_) => false,
1028 Object(ref d1) => {
1029 unsafe {
1030 let mut d0_flat = ~[];
1031 let mut d1_flat = ~[];
1032
Tim Chevalier3e7da962013-01-11 04:09:161033 // FIXME #4430: this is horribly inefficient...
Daniel Micay9599cc82013-02-08 02:03:131034 for d0.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301035 d0_flat.push((@copy *k, @copy *v));
1036 }
1037 d0_flat.qsort();
1038
Daniel Micay9599cc82013-02-08 02:03:131039 for d1.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301040 d1_flat.push((@copy *k, @copy *v));
1041 }
1042 d1_flat.qsort();
1043
1044 d0_flat < d1_flat
1045 }
1046 }
1047 Null => true
1048 }
1049 }
1050
1051 Null => {
1052 match *other {
1053 Number(_) | String(_) | Boolean(_) | List(_) |
1054 Object(_) =>
1055 false,
1056 Null => true
1057 }
1058 }
1059 }
1060 }
Patrick Walton318e5342012-11-15 02:59:301061 pure fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) }
Patrick Walton318e5342012-11-15 02:59:301062 pure fn ge(&self, other: &Json) -> bool { !(*self).lt(other) }
Patrick Walton318e5342012-11-15 02:59:301063 pure fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) }
Patrick Walton22b87572012-09-08 01:53:141064}
1065
Patrick Walton91436882013-02-14 19:47:001066impl Eq for Error {
Patrick Walton318e5342012-11-15 02:59:301067 pure fn eq(&self, other: &Error) -> bool {
1068 (*self).line == other.line &&
1069 (*self).col == other.col &&
1070 (*self).msg == other.msg
1071 }
Patrick Walton318e5342012-11-15 02:59:301072 pure fn ne(&self, other: &Error) -> bool { !(*self).eq(other) }
Patrick Walton9117dcb2012-09-20 01:00:261073}
Patrick Walton96534362012-08-27 23:26:351074
Ben Striegel0fed29c2013-03-08 02:11:091075trait ToJson { fn to_json(&self) -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:321076
Patrick Walton91436882013-02-14 19:47:001077impl ToJson for Json {
Ben Striegel0fed29c2013-03-08 02:11:091078 fn to_json(&self) -> Json { copy *self }
Erick Tryzelaared5af702012-05-28 19:10:321079}
1080
Patrick Walton91436882013-02-14 19:47:001081impl ToJson for @Json {
Ben Striegel0fed29c2013-03-08 02:11:091082 fn to_json(&self) -> Json { (**self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:541083}
1084
Patrick Walton91436882013-02-14 19:47:001085impl ToJson for int {
Ben Striegel0fed29c2013-03-08 02:11:091086 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541087}
1088
Patrick Walton91436882013-02-14 19:47:001089impl ToJson for i8 {
Ben Striegel0fed29c2013-03-08 02:11:091090 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321091}
1092
Patrick Walton91436882013-02-14 19:47:001093impl ToJson for i16 {
Ben Striegel0fed29c2013-03-08 02:11:091094 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321095}
1096
Patrick Walton91436882013-02-14 19:47:001097impl ToJson for i32 {
Ben Striegel0fed29c2013-03-08 02:11:091098 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321099}
1100
Patrick Walton91436882013-02-14 19:47:001101impl ToJson for i64 {
Ben Striegel0fed29c2013-03-08 02:11:091102 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321103}
1104
Patrick Walton91436882013-02-14 19:47:001105impl ToJson for uint {
Ben Striegel0fed29c2013-03-08 02:11:091106 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541107}
1108
Patrick Walton91436882013-02-14 19:47:001109impl ToJson for u8 {
Ben Striegel0fed29c2013-03-08 02:11:091110 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321111}
1112
Patrick Walton91436882013-02-14 19:47:001113impl ToJson for u16 {
Ben Striegel0fed29c2013-03-08 02:11:091114 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321115}
1116
Patrick Walton91436882013-02-14 19:47:001117impl ToJson for u32 {
Ben Striegel0fed29c2013-03-08 02:11:091118 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321119}
1120
Patrick Walton91436882013-02-14 19:47:001121impl ToJson for u64 {
Ben Striegel0fed29c2013-03-08 02:11:091122 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321123}
1124
Patrick Walton91436882013-02-14 19:47:001125impl ToJson for float {
Ben Striegel0fed29c2013-03-08 02:11:091126 fn to_json(&self) -> Json { Number(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321127}
1128
Patrick Walton91436882013-02-14 19:47:001129impl ToJson for f32 {
Ben Striegel0fed29c2013-03-08 02:11:091130 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321131}
1132
Patrick Walton91436882013-02-14 19:47:001133impl ToJson for f64 {
Ben Striegel0fed29c2013-03-08 02:11:091134 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321135}
1136
Patrick Walton91436882013-02-14 19:47:001137impl ToJson for () {
Ben Striegel0fed29c2013-03-08 02:11:091138 fn to_json(&self) -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321139}
1140
Patrick Walton91436882013-02-14 19:47:001141impl ToJson for bool {
Ben Striegel0fed29c2013-03-08 02:11:091142 fn to_json(&self) -> Json { Boolean(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321143}
1144
Patrick Walton91436882013-02-14 19:47:001145impl ToJson for ~str {
Ben Striegel0fed29c2013-03-08 02:11:091146 fn to_json(&self) -> Json { String(copy *self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511147}
1148
Patrick Walton91436882013-02-14 19:47:001149impl ToJson for @~str {
Ben Striegel0fed29c2013-03-08 02:11:091150 fn to_json(&self) -> Json { String(copy **self) }
Erick Tryzelaared5af702012-05-28 19:10:321151}
1152
Patrick Waltonbf2a2252013-02-21 01:07:171153impl<A:ToJson,B:ToJson> ToJson for (A, B) {
Ben Striegel0fed29c2013-03-08 02:11:091154 fn to_json(&self) -> Json {
1155 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181156 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421157 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561158 }
1159 }
Erick Tryzelaared5af702012-05-28 19:10:321160 }
1161}
1162
Patrick Waltonbf2a2252013-02-21 01:07:171163impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
Ben Striegel0fed29c2013-03-08 02:11:091164 fn to_json(&self) -> Json {
1165 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181166 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421167 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561168 }
1169 }
Erick Tryzelaared5af702012-05-28 19:10:321170 }
1171}
1172
Patrick Waltonbf2a2252013-02-21 01:07:171173impl<A:ToJson> ToJson for ~[A] {
Ben Striegel0fed29c2013-03-08 02:11:091174 fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321175}
1176
Patrick Waltonbf2a2252013-02-21 01:07:171177impl<A:ToJson + Copy> ToJson for LinearMap<~str, A> {
Ben Striegel0fed29c2013-03-08 02:11:091178 fn to_json(&self) -> Json {
Daniel Micay7f0fa142013-01-23 22:06:321179 let mut d = LinearMap::new();
Daniel Micay9599cc82013-02-08 02:03:131180 for self.each |&(key, value)| {
Erick Tryzelaar49d00b22012-09-24 16:55:421181 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321182 }
Erick Tryzelaar49d00b22012-09-24 16:55:421183 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321184 }
1185}
1186
Patrick Waltonbf2a2252013-02-21 01:07:171187impl<A:ToJson> ToJson for Option<A> {
Ben Striegel0fed29c2013-03-08 02:11:091188 fn to_json(&self) -> Json {
1189 match *self {
Ben Striegela605fd02012-08-11 14:08:421190 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181191 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321192 }
1193 }
1194}
1195
Patrick Walton91436882013-02-14 19:47:001196impl to_str::ToStr for Json {
Erick Tryzelaar9adfa592013-02-04 04:47:261197 pure fn to_str(&self) -> ~str { to_str(self) }
Erick Tryzelaared5af702012-05-28 19:10:321198}
1199
Patrick Walton91436882013-02-14 19:47:001200impl to_str::ToStr for Error {
Erick Tryzelaar9adfa592013-02-04 04:47:261201 pure fn to_str(&self) -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521202 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381203 }
1204}
1205
Brian Anderson6e27b272012-01-18 03:05:071206#[cfg(test)]
1207mod tests {
Patrick Walton2db3abd2013-01-09 03:37:251208 use core::prelude::*;
1209
1210 use json::*;
Alex Crichton2df07dd2013-02-25 19:11:211211 use serialize;
Patrick Walton2db3abd2013-01-09 03:37:251212
Patrick Waltonfa5ee932012-12-28 02:24:181213 use core::result;
Daniel Micay7f0fa142013-01-23 22:06:321214 use core::hashmap::linear::LinearMap;
John Clementsf91160b2013-02-08 01:06:261215 use core::cmp;
1216
Patrick Waltonfa5ee932012-12-28 02:24:181217
Erick Tryzelaar49d00b22012-09-24 16:55:421218 fn mk_object(items: &[(~str, Json)]) -> Json {
Daniel Micaybba55202013-01-24 02:09:501219 let mut d = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:321220
Erick Tryzelaar49d00b22012-09-24 16:55:421221 for items.each |item| {
1222 match *item {
Luqman Aden4cf51c22013-02-15 07:30:301223 (copy key, copy value) => { d.insert(key, value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421224 }
Erick Tryzelaar012dec52012-02-26 00:39:321225 };
1226
Luqman Aden4cf51c22013-02-15 07:30:301227 Object(d)
Brian Anderson6e27b272012-01-18 03:05:071228 }
1229
1230 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321231 fn test_write_null() {
Erick Tryzelaar49d00b22012-09-24 16:55:421232 assert to_str(&Null) == ~"null";
Brian Anderson6e27b272012-01-18 03:05:071233 }
1234
1235 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421236 fn test_write_number() {
1237 assert to_str(&Number(3f)) == ~"3";
1238 assert to_str(&Number(3.1f)) == ~"3.1";
1239 assert to_str(&Number(-1.5f)) == ~"-1.5";
1240 assert to_str(&Number(0.5f)) == ~"0.5";
Brian Anderson6e27b272012-01-18 03:05:071241 }
1242
1243 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321244 fn test_write_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421245 assert to_str(&String(~"")) == ~"\"\"";
1246 assert to_str(&String(~"foo")) == ~"\"foo\"";
Brian Anderson6e27b272012-01-18 03:05:071247 }
1248
1249 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321250 fn test_write_bool() {
Erick Tryzelaar49d00b22012-09-24 16:55:421251 assert to_str(&Boolean(true)) == ~"true";
1252 assert to_str(&Boolean(false)) == ~"false";
Brian Anderson6e27b272012-01-18 03:05:071253 }
1254
1255 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321256 fn test_write_list() {
Erick Tryzelaar49d00b22012-09-24 16:55:421257 assert to_str(&List(~[])) == ~"[]";
1258 assert to_str(&List(~[Boolean(true)])) == ~"[true]";
1259 assert to_str(&List(~[
Ben Striegela605fd02012-08-11 14:08:421260 Boolean(false),
1261 Null,
Erick Tryzelaar49d00b22012-09-24 16:55:421262 List(~[String(~"foo\nbar"), Number(3.5f)])
1263 ])) == ~"[false,null,[\"foo\\nbar\",3.5]]";
Erick Tryzelaar012dec52012-02-26 00:39:321264 }
1265
1266 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421267 fn test_write_object() {
1268 assert to_str(&mk_object(~[])) == ~"{}";
1269 assert to_str(&mk_object(~[(~"a", Boolean(true))]))
1270 == ~"{\"a\":true}";
1271 let a = mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421272 (~"a", Boolean(true)),
Erick Tryzelaar49d00b22012-09-24 16:55:421273 (~"b", List(~[
1274 mk_object(~[(~"c", String(~"\x0c\r"))]),
1275 mk_object(~[(~"d", String(~""))])
Michael Sullivan98e161f2012-06-29 23:26:561276 ]))
Graydon Hoare11871b82012-08-30 23:27:151277 ]);
Erick Tryzelaar49d00b22012-09-24 16:55:421278 // We can't compare the strings directly because the object fields be
1279 // printed in a different order.
1280 let b = result::unwrap(from_str(to_str(&a)));
Graydon Hoare11871b82012-08-30 23:27:151281 assert a == b;
Erick Tryzelaar012dec52012-02-26 00:39:321282 }
1283
John Clementsf91160b2013-02-08 01:06:261284 // two fns copied from libsyntax/util/testing.rs.
1285 // Should they be in their own crate?
Patrick Waltonbf2a2252013-02-21 01:07:171286 pub pure fn check_equal_ptr<T:cmp::Eq> (given : &T, expected: &T) {
John Clementsf91160b2013-02-08 01:06:261287 if !((given == expected) && (expected == given )) {
Nick Desaulniers4699ac62013-02-14 21:09:091288 fail!(fmt!("given %?, expected %?",given,expected));
John Clementsf91160b2013-02-08 01:06:261289 }
1290 }
1291
Patrick Waltonbf2a2252013-02-21 01:07:171292 pub pure fn check_equal<T:cmp::Eq> (given : T, expected: T) {
John Clementsf91160b2013-02-08 01:06:261293 if !((given == expected) && (expected == given )) {
Nick Desaulniers4699ac62013-02-14 21:09:091294 fail!(fmt!("given %?, expected %?",given,expected));
John Clementsf91160b2013-02-08 01:06:261295 }
1296 }
1297
John Clementsf91160b2013-02-08 01:06:261298 #[test]
1299 fn test_write_enum () {
Seo Sanghyeon9324f492013-02-14 13:51:011300 let bw = @io::BytesWriter();
John Clementsf91160b2013-02-08 01:06:261301 let bww : @io::Writer = (bw as @io::Writer);
1302 let encoder = (@Encoder(bww) as @serialize::Encoder);
1303 do encoder.emit_enum(~"animal") {
1304 do encoder.emit_enum_variant (~"frog",37,1242) {
1305 // name of frog:
1306 do encoder.emit_enum_variant_arg (0) {
1307 encoder.emit_owned_str(~"Henry")
1308 }
1309 // mass of frog in grams:
1310 do encoder.emit_enum_variant_arg (1) {
1311 encoder.emit_int(349);
1312 }
1313 }
1314 }
1315 check_equal(str::from_bytes(bw.bytes.data),
John Clementsc952c042013-02-08 23:36:401316 ~"[\"frog\",[\"Henry\",349]]");
1317 }
1318
1319 #[test]
1320 fn test_write_some () {
Seo Sanghyeon9324f492013-02-14 13:51:011321 let bw = @io::BytesWriter();
John Clementsc952c042013-02-08 23:36:401322 let bww : @io::Writer = (bw as @io::Writer);
1323 let encoder = (@Encoder(bww) as @serialize::Encoder);
1324 do encoder.emit_enum(~"Option") {
1325 do encoder.emit_enum_variant (~"Some",37,1242) {
1326 do encoder.emit_enum_variant_arg (0) {
1327 encoder.emit_owned_str(~"jodhpurs")
1328 }
1329 }
1330 }
1331 check_equal(str::from_bytes(bw.bytes.data),
1332 ~"\"jodhpurs\"");
1333 }
1334
1335 #[test]
1336 fn test_write_none () {
Seo Sanghyeon9324f492013-02-14 13:51:011337 let bw = @io::BytesWriter();
John Clementsc952c042013-02-08 23:36:401338 let bww : @io::Writer = (bw as @io::Writer);
1339 let encoder = (@Encoder(bww) as @serialize::Encoder);
1340 do encoder.emit_enum(~"Option") {
1341 do encoder.emit_enum_variant (~"None",37,1242) {
1342 }
1343 }
1344 check_equal(str::from_bytes(bw.bytes.data),
1345 ~"null");
John Clementsf91160b2013-02-08 01:06:261346 }
1347
Erick Tryzelaar012dec52012-02-26 00:39:321348 #[test]
1349 fn test_trailing_characters() {
Michael Sullivan92743dc2012-07-14 05:57:481350 assert from_str(~"nulla") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421351 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481352 assert from_str(~"truea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421353 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481354 assert from_str(~"falsea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421355 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481356 assert from_str(~"1a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421357 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481358 assert from_str(~"[]a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421359 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481360 assert from_str(~"{}a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421361 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Erick Tryzelaar012dec52012-02-26 00:39:321362 }
1363
1364 #[test]
1365 fn test_read_identifiers() {
Michael Sullivan92743dc2012-07-14 05:57:481366 assert from_str(~"n") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421367 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481368 assert from_str(~"nul") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421369 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321370
Michael Sullivan92743dc2012-07-14 05:57:481371 assert from_str(~"t") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421372 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481373 assert from_str(~"truz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421374 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321375
Michael Sullivan92743dc2012-07-14 05:57:481376 assert from_str(~"f") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421377 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481378 assert from_str(~"faz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421379 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321380
Ben Striegela605fd02012-08-11 14:08:421381 assert from_str(~"null") == Ok(Null);
1382 assert from_str(~"true") == Ok(Boolean(true));
1383 assert from_str(~"false") == Ok(Boolean(false));
1384 assert from_str(~" null ") == Ok(Null);
1385 assert from_str(~" true ") == Ok(Boolean(true));
1386 assert from_str(~" false ") == Ok(Boolean(false));
Erick Tryzelaar012dec52012-02-26 00:39:321387 }
1388
1389 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421390 fn test_read_number() {
Michael Sullivan92743dc2012-07-14 05:57:481391 assert from_str(~"+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421392 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481393 assert from_str(~".") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421394 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321395
Michael Sullivan92743dc2012-07-14 05:57:481396 assert from_str(~"-") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421397 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481398 assert from_str(~"00") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421399 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481400 assert from_str(~"1.") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421401 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481402 assert from_str(~"1e") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421403 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481404 assert from_str(~"1e+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421405 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"});
Erick Tryzelaar012dec52012-02-26 00:39:321406
Erick Tryzelaar49d00b22012-09-24 16:55:421407 assert from_str(~"3") == Ok(Number(3f));
1408 assert from_str(~"3.1") == Ok(Number(3.1f));
1409 assert from_str(~"-1.2") == Ok(Number(-1.2f));
1410 assert from_str(~"0.4") == Ok(Number(0.4f));
1411 assert from_str(~"0.4e5") == Ok(Number(0.4e5f));
1412 assert from_str(~"0.4e+15") == Ok(Number(0.4e15f));
1413 assert from_str(~"0.4e-01") == Ok(Number(0.4e-01f));
1414 assert from_str(~" 3 ") == Ok(Number(3f));
Erick Tryzelaar012dec52012-02-26 00:39:321415 }
1416
1417 #[test]
1418 fn test_read_str() {
Michael Sullivan92743dc2012-07-14 05:57:481419 assert from_str(~"\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421420 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"});
Michael Sullivan92743dc2012-07-14 05:57:481421 assert from_str(~"\"lol") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421422 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"});
Erick Tryzelaar012dec52012-02-26 00:39:321423
Erick Tryzelaar49d00b22012-09-24 16:55:421424 assert from_str(~"\"\"") == Ok(String(~""));
1425 assert from_str(~"\"foo\"") == Ok(String(~"foo"));
1426 assert from_str(~"\"\\\"\"") == Ok(String(~"\""));
1427 assert from_str(~"\"\\b\"") == Ok(String(~"\x08"));
1428 assert from_str(~"\"\\n\"") == Ok(String(~"\n"));
1429 assert from_str(~"\"\\r\"") == Ok(String(~"\r"));
1430 assert from_str(~"\"\\t\"") == Ok(String(~"\t"));
1431 assert from_str(~" \"foo\" ") == Ok(String(~"foo"));
Erick Tryzelaar012dec52012-02-26 00:39:321432 }
1433
1434 #[test]
Kevin Cantucf386182012-08-31 04:03:191435 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421436 assert from_str(~"\"\\u12ab\"") == Ok(String(~"\u12ab"));
1437 assert from_str(~"\"\\uAB12\"") == Ok(String(~"\uAB12"));
Kevin Cantucf386182012-08-31 04:03:191438 }
1439
1440 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321441 fn test_read_list() {
Michael Sullivan92743dc2012-07-14 05:57:481442 assert from_str(~"[") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421443 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481444 assert from_str(~"[1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421445 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"});
Michael Sullivan92743dc2012-07-14 05:57:481446 assert from_str(~"[1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421447 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481448 assert from_str(~"[1,]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421449 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481450 assert from_str(~"[6 7]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421451 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"});
Erick Tryzelaar012dec52012-02-26 00:39:321452
Erick Tryzelaar49d00b22012-09-24 16:55:421453 assert from_str(~"[]") == Ok(List(~[]));
1454 assert from_str(~"[ ]") == Ok(List(~[]));
1455 assert from_str(~"[true]") == Ok(List(~[Boolean(true)]));
1456 assert from_str(~"[ false ]") == Ok(List(~[Boolean(false)]));
1457 assert from_str(~"[null]") == Ok(List(~[Null]));
1458 assert from_str(~"[3, 1]") == Ok(List(~[Number(3f), Number(1f)]));
1459 assert from_str(~"\n[3, 2]\n") == Ok(List(~[Number(3f), Number(2f)]));
Michael Sullivan92743dc2012-07-14 05:57:481460 assert from_str(~"[2, [4, 1]]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421461 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])]));
Erick Tryzelaar012dec52012-02-26 00:39:321462 }
1463
1464 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421465 fn test_read_object() {
Michael Sullivan92743dc2012-07-14 05:57:481466 assert from_str(~"{") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421467 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481468 assert from_str(~"{ ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421469 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481470 assert from_str(~"{1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421471 Err(Error {line: 1u, col: 2u, msg: @~"key must be a string"});
Michael Sullivan92743dc2012-07-14 05:57:481472 assert from_str(~"{ \"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421473 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481474 assert from_str(~"{\"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421475 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481476 assert from_str(~"{\"a\" ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421477 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321478
Michael Sullivan92743dc2012-07-14 05:57:481479 assert from_str(~"{\"a\" 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421480 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"});
Michael Sullivan92743dc2012-07-14 05:57:481481 assert from_str(~"{\"a\":") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421482 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481483 assert from_str(~"{\"a\":1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421484 Err(Error {line: 1u, col: 7u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481485 assert from_str(~"{\"a\":1 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421486 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"});
Michael Sullivan92743dc2012-07-14 05:57:481487 assert from_str(~"{\"a\":1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421488 Err(Error {line: 1u, col: 8u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321489
Erick Tryzelaar49d00b22012-09-24 16:55:421490 assert result::unwrap(from_str(~"{}")) == mk_object(~[]);
1491 assert result::unwrap(from_str(~"{\"a\": 3}")) ==
1492 mk_object(~[(~"a", Number(3.0f))]);
Erick Tryzelaar012dec52012-02-26 00:39:321493
Erick Tryzelaar49d00b22012-09-24 16:55:421494 assert result::unwrap(from_str(~"{ \"a\": null, \"b\" : true }")) ==
1495 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421496 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421497 (~"b", Boolean(true))]);
1498 assert result::unwrap(
1499 from_str(~"\n{ \"a\": null, \"b\" : true }\n")) ==
1500 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421501 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421502 (~"b", Boolean(true))]);
1503 assert result::unwrap(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")) ==
1504 mk_object(~[
1505 (~"a", Number(1.0)),
1506 (~"b", List(~[Boolean(true)]))
1507 ]);
1508 assert result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481509 ~"{" +
1510 ~"\"a\": 1.0, " +
1511 ~"\"b\": [" +
1512 ~"true," +
1513 ~"\"foo\\nbar\", " +
1514 ~"{ \"c\": {\"d\": null} } " +
1515 ~"]" +
Erick Tryzelaar49d00b22012-09-24 16:55:421516 ~"}")) ==
1517 mk_object(~[
1518 (~"a", Number(1.0f)),
1519 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421520 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421521 String(~"foo\nbar"),
1522 mk_object(~[
1523 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561524 ])
1525 ]))
Erick Tryzelaar49d00b22012-09-24 16:55:421526 ]);
Erick Tryzelaar012dec52012-02-26 00:39:321527 }
1528
1529 #[test]
1530 fn test_multiline_errors() {
Michael Sullivan92743dc2012-07-14 05:57:481531 assert from_str(~"{\n \"foo\":\n \"bar\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421532 Err(Error {line: 3u, col: 8u, msg: @~"EOF while parsing object"});
Brian Anderson6e27b272012-01-18 03:05:071533 }
1534}