blob: f426b74736ad3a44950111b553139d1ce045ea96 [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
Erick Tryzelaarcefecd82013-03-13 18:29:0517use core::prelude::*;
18use core::io::{WriterUtil, ReaderUtil};
Daniel Micaycc148b52013-04-03 13:28:3619use core::hashmap::HashMap;
Erick Tryzelaarcefecd82013-03-13 18:29:0520
Patrick Waltoneb4d39e2013-01-26 00:57:3921use serialize::Encodable;
Patrick Walton57c59992012-12-23 22:41:3722use serialize;
Patrick Walton22b87572012-09-08 01:53:1423use sort::Sort;
Elly Jonesbd726262011-11-07 19:01:2824
Gareth Daniel Smithbe014162012-07-04 21:53:1225/// Represents a json value
Erick Tryzelaar49d00b22012-09-24 16:55:4226pub enum Json {
27 Number(float),
28 String(~str),
Ben Striegela605fd02012-08-11 14:08:4229 Boolean(bool),
Erick Tryzelaar49d00b22012-09-24 16:55:4230 List(List),
31 Object(~Object),
Ben Striegela605fd02012-08-11 14:08:4232 Null,
Elly Jonesbd726262011-11-07 19:01:2833}
34
Erick Tryzelaar49d00b22012-09-24 16:55:4235pub type List = ~[Json];
Daniel Micaycc148b52013-04-03 13:28:3636pub type Object = HashMap<~str, Json>;
Erick Tryzelaar49d00b22012-09-24 16:55:4237
Andrew Paseltiner45677ee2013-03-22 20:09:2038#[deriving(Eq)]
Erick Tryzelaar49d00b22012-09-24 16:55:4239pub struct Error {
Erick Tryzelaar012dec52012-02-26 00:39:3240 line: uint,
41 col: uint,
Michael Sullivan92743dc2012-07-14 05:57:4842 msg: @~str,
Kevin Cantud47cb102012-08-30 23:39:5643}
44
Kevin Cantuc43426e2012-09-13 05:09:5545fn escape_str(s: &str) -> ~str {
Michael Sullivan92743dc2012-07-14 05:57:4846 let mut escaped = ~"\"";
Erick Tryzelaarcefecd82013-03-13 18:29:0547 for str::each_char(s) |c| {
Brian Andersonecaf9e32012-08-06 19:34:0848 match c {
Brian Anderson025d8662012-08-04 02:59:0449 '"' => escaped += ~"\\\"",
50 '\\' => escaped += ~"\\\\",
51 '\x08' => escaped += ~"\\b",
52 '\x0c' => escaped += ~"\\f",
53 '\n' => escaped += ~"\\n",
54 '\r' => escaped += ~"\\r",
55 '\t' => escaped += ~"\\t",
56 _ => escaped += str::from_char(c)
Erick Tryzelaarb361f6c2012-06-13 00:20:5157 }
58 };
59
Michael Sullivan92743dc2012-07-14 05:57:4860 escaped += ~"\"";
Erick Tryzelaarb361f6c2012-06-13 00:20:5161
62 escaped
63}
64
Erick Tryzelaar49d00b22012-09-24 16:55:4265fn spaces(n: uint) -> ~str {
66 let mut ss = ~"";
Tim Chevalier5a8ba072012-10-11 21:12:5067 for n.times { str::push_str(&mut ss, " "); }
Erick Tryzelaar49d00b22012-09-24 16:55:4268 return ss;
69}
70
Erick Tryzelaar8650c6f2012-12-18 03:31:0471pub struct Encoder {
Patrick Waltonb1c69982013-03-12 20:00:5072 priv wr: @io::Writer,
Erick Tryzelaar49d00b22012-09-24 16:55:4273}
74
Patrick Waltonb1c69982013-03-12 20:00:5075pub fn Encoder(wr: @io::Writer) -> Encoder {
Erick Tryzelaar8650c6f2012-12-18 03:31:0476 Encoder { wr: wr }
Erick Tryzelaar49d00b22012-09-24 16:55:4277}
78
Patrick Walton07c3f5c2013-02-27 01:12:0079impl serialize::Encoder for Encoder {
Erick Tryzelaar49d00b22012-09-24 16:55:4280 fn emit_nil(&self) { self.wr.write_str("null") }
81
82 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
83 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
84 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
85 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
86 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
87
88 fn emit_int(&self, v: int) { self.emit_float(v as float); }
89 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
90 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
91 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
92 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
93
94 fn emit_bool(&self, v: bool) {
95 if v {
96 self.wr.write_str("true");
97 } else {
98 self.wr.write_str("false");
99 }
100 }
101
102 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
103 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
104 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39105 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42106 }
107
Erick Tryzelaar8b43c622013-03-29 03:51:05108 fn emit_char(&self, v: char) { self.emit_str(str::from_char(v)) }
109 fn emit_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
Erick Tryzelaar81423a32012-09-27 04:35:13110
Erick Tryzelaar8b43c622013-03-29 03:51:05111 fn emit_enum(&self, _name: &str, f: &fn()) { f() }
Erick Tryzelaar4d995e62013-03-27 07:14:52112 fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) {
Erick Tryzelaar478e4492013-03-26 22:26:05113 // enums are encoded as strings or vectors:
Erick Tryzelaar4d995e62013-03-27 07:14:52114 // Bunny => "Bunny"
John Clementsc952c042013-02-08 23:36:40115 // Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
John Clements7736ed62013-02-09 02:58:33116
Erick Tryzelaar478e4492013-03-26 22:26:05117 if cnt == 0 {
Erick Tryzelaar4d995e62013-03-27 07:14:52118 self.wr.write_str(escape_str(name));
John Clementsc952c042013-02-08 23:36:40119 } else {
120 self.wr.write_char('[');
121 self.wr.write_str(escape_str(name));
122 self.wr.write_char(',');
John Clementsc952c042013-02-08 23:36:40123 f();
124 self.wr.write_char(']');
John Clementsc952c042013-02-08 23:36:40125 }
Erick Tryzelaar49d00b22012-09-24 16:55:42126 }
John Clementsf91160b2013-02-08 01:06:26127
Patrick Waltond18f7852013-03-07 22:38:38128 fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) {
John Clementsc952c042013-02-08 23:36:40129 if (idx != 0) {self.wr.write_char(',');}
John Clementsfe823742013-02-07 01:19:11130 f();
Erick Tryzelaar49d00b22012-09-24 16:55:42131 }
132
Erick Tryzelaar590bbce2013-03-29 04:34:47133 fn emit_seq(&self, _len: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42134 self.wr.write_char('[');
135 f();
136 self.wr.write_char(']');
137 }
John Clements7736ed62013-02-09 02:58:33138
Erick Tryzelaar590bbce2013-03-29 04:34:47139 fn emit_seq_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42140 if idx != 0 { self.wr.write_char(','); }
141 f()
142 }
143
Patrick Waltond18f7852013-03-07 22:38:38144 fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13145 self.wr.write_char('{');
146 f();
147 self.wr.write_char('}');
148 }
Patrick Waltond18f7852013-03-07 22:38:38149 fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42150 if idx != 0 { self.wr.write_char(','); }
151 self.wr.write_str(escape_str(name));
152 self.wr.write_char(':');
153 f();
154 }
Erick Tryzelaar81423a32012-09-27 04:35:13155
Erick Tryzelaar478e4492013-03-26 22:26:05156 fn emit_option(&self, f: &fn()) { f(); }
157 fn emit_option_none(&self) { self.emit_nil(); }
158 fn emit_option_some(&self, f: &fn()) { f(); }
Erick Tryzelaard1a83e62013-03-29 16:04:35159
160 fn emit_map(&self, _len: uint, f: &fn()) {
161 self.wr.write_char('{');
162 f();
163 self.wr.write_char('}');
164 }
165
166 fn emit_map_elt_key(&self, idx: uint, f: &fn()) {
167 if idx != 0 { self.wr.write_char(','); }
168 f()
169 }
170
171 fn emit_map_elt_val(&self, _idx: uint, f: &fn()) {
172 self.wr.write_char(':');
173 f()
174 }
Erick Tryzelaar49d00b22012-09-24 16:55:42175}
176
Erick Tryzelaar8650c6f2012-12-18 03:31:04177pub struct PrettyEncoder {
Patrick Waltonb1c69982013-03-12 20:00:50178 priv wr: @io::Writer,
Erick Tryzelaar49d00b22012-09-24 16:55:42179 priv mut indent: uint,
180}
181
Patrick Waltonb1c69982013-03-12 20:00:50182pub fn PrettyEncoder(wr: @io::Writer) -> PrettyEncoder {
Erick Tryzelaar8650c6f2012-12-18 03:31:04183 PrettyEncoder { wr: wr, indent: 0 }
Erick Tryzelaar49d00b22012-09-24 16:55:42184}
185
Patrick Walton07c3f5c2013-02-27 01:12:00186impl serialize::Encoder for PrettyEncoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42187 fn emit_nil(&self) { self.wr.write_str("null") }
188
189 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
190 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
191 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
192 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
193 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
194
195 fn emit_int(&self, v: int) { self.emit_float(v as float); }
196 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
197 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
198 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
199 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
200
201 fn emit_bool(&self, v: bool) {
202 if v {
203 self.wr.write_str("true");
204 } else {
205 self.wr.write_str("false");
206 }
207 }
208
209 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
210 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
211 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39212 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42213 }
214
Erick Tryzelaar8b43c622013-03-29 03:51:05215 fn emit_char(&self, v: char) { self.emit_str(str::from_char(v)) }
216 fn emit_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
Erick Tryzelaar49d00b22012-09-24 16:55:42217
Erick Tryzelaarc9188c82013-03-27 00:34:49218 fn emit_enum(&self, _name: &str, f: &fn()) { f() }
219 fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) {
Erick Tryzelaar478e4492013-03-26 22:26:05220 if cnt == 0 {
Erick Tryzelaar4d995e62013-03-27 07:14:52221 self.wr.write_str(escape_str(name));
Erick Tryzelaar49d00b22012-09-24 16:55:42222 } else {
Erick Tryzelaarc9188c82013-03-27 00:34:49223 self.wr.write_char('[');
224 self.indent += 2;
225 self.wr.write_char('\n');
226 self.wr.write_str(spaces(self.indent));
227 self.wr.write_str(escape_str(name));
Erick Tryzelaar4d995e62013-03-27 07:14:52228 self.wr.write_str(",\n");
229 f();
230 self.wr.write_char('\n');
Erick Tryzelaarc9188c82013-03-27 00:34:49231 self.indent -= 2;
Erick Tryzelaar4d995e62013-03-27 07:14:52232 self.wr.write_str(spaces(self.indent));
Erick Tryzelaarc9188c82013-03-27 00:34:49233 self.wr.write_char(']');
Erick Tryzelaar49d00b22012-09-24 16:55:42234 }
235 }
Erick Tryzelaarc9188c82013-03-27 00:34:49236 fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) {
237 if idx != 0 {
238 self.wr.write_str(",\n");
239 }
240 self.wr.write_str(spaces(self.indent));
Erick Tryzelaar49d00b22012-09-24 16:55:42241 f()
242 }
243
Erick Tryzelaar590bbce2013-03-29 04:34:47244 fn emit_seq(&self, len: uint, f: &fn()) {
Erick Tryzelaarc9188c82013-03-27 00:34:49245 if len == 0 {
246 self.wr.write_str("[]");
247 } else {
248 self.wr.write_char('[');
249 self.indent += 2;
250 f();
251 self.wr.write_char('\n');
252 self.indent -= 2;
253 self.wr.write_str(spaces(self.indent));
254 self.wr.write_char(']');
255 }
Erick Tryzelaar49d00b22012-09-24 16:55:42256 }
Erick Tryzelaar590bbce2013-03-29 04:34:47257 fn emit_seq_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42258 if idx == 0 {
259 self.wr.write_char('\n');
260 } else {
261 self.wr.write_str(",\n");
262 }
263 self.wr.write_str(spaces(self.indent));
264 f()
265 }
266
Erick Tryzelaarc9188c82013-03-27 00:34:49267 fn emit_struct(&self, _name: &str, len: uint, f: &fn()) {
268 if len == 0 {
269 self.wr.write_str("{}");
270 } else {
Erick Tryzelaar90b36582013-03-29 05:19:43271 self.wr.write_char('{');
272 self.indent += 2;
273 f();
274 self.wr.write_char('\n');
275 self.indent -= 2;
276 self.wr.write_str(spaces(self.indent));
277 self.wr.write_char('}');
Erick Tryzelaarc9188c82013-03-27 00:34:49278 }
Erick Tryzelaar81423a32012-09-27 04:35:13279 }
Patrick Waltond18f7852013-03-07 22:38:38280 fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42281 if idx == 0 {
282 self.wr.write_char('\n');
283 } else {
284 self.wr.write_str(",\n");
285 }
286 self.wr.write_str(spaces(self.indent));
287 self.wr.write_str(escape_str(name));
288 self.wr.write_str(": ");
289 f();
290 }
Erick Tryzelaar478e4492013-03-26 22:26:05291
292 fn emit_option(&self, f: &fn()) { f(); }
293 fn emit_option_none(&self) { self.emit_nil(); }
294 fn emit_option_some(&self, f: &fn()) { f(); }
Erick Tryzelaard1a83e62013-03-29 16:04:35295
296 fn emit_map(&self, len: uint, f: &fn()) {
297 if len == 0 {
298 self.wr.write_str("{}");
299 } else {
300 self.wr.write_char('{');
301 self.indent += 2;
302 f();
303 self.wr.write_char('\n');
304 self.indent -= 2;
305 self.wr.write_str(spaces(self.indent));
306 self.wr.write_char('}');
307 }
308 }
309 fn emit_map_elt_key(&self, idx: uint, f: &fn()) {
310 if idx == 0 {
311 self.wr.write_char('\n');
312 } else {
313 self.wr.write_str(",\n");
314 }
315 self.wr.write_str(spaces(self.indent));
316 f();
317 }
318
319 fn emit_map_elt_val(&self, _idx: uint, f: &fn()) {
320 self.wr.write_str(": ");
321 f();
322 }
Erick Tryzelaar49d00b22012-09-24 16:55:42323}
324
Erick Tryzelaar90b36582013-03-29 05:19:43325impl<E: serialize::Encoder> serialize::Encodable<E> for Json {
326 fn encode(&self, e: &E) {
Erick Tryzelaarab89b5c2012-10-13 16:11:33327 match *self {
Erick Tryzelaar90b36582013-03-29 05:19:43328 Number(v) => v.encode(e),
329 String(ref v) => v.encode(e),
330 Boolean(v) => v.encode(e),
331 List(ref v) => v.encode(e),
Erick Tryzelaard1a83e62013-03-29 16:04:35332 Object(ref v) => v.encode(e),
Erick Tryzelaar90b36582013-03-29 05:19:43333 Null => e.emit_nil(),
Erick Tryzelaarab89b5c2012-10-13 16:11:33334 }
335 }
336}
337
Erick Tryzelaar8650c6f2012-12-18 03:31:04338/// Encodes a json value into a io::writer
Patrick Waltonb1c69982013-03-12 20:00:50339pub fn to_writer(wr: @io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04340 json.encode(&Encoder(wr))
Erick Tryzelaar49d00b22012-09-24 16:55:42341}
342
Erick Tryzelaar8650c6f2012-12-18 03:31:04343/// Encodes a json value into a string
Patrick Waltonc1084092013-03-22 04:34:30344pub fn to_str(json: &Json) -> ~str {
Patrick Walton54b2cad2013-01-23 19:43:58345 unsafe {
346 // ugh, should be safe
347 io::with_str_writer(|wr| to_writer(wr, json))
348 }
Elly Jonesbd726262011-11-07 19:01:28349}
350
Erick Tryzelaar8650c6f2012-12-18 03:31:04351/// Encodes a json value into a io::writer
Patrick Waltonb1c69982013-03-12 20:00:50352pub fn to_pretty_writer(wr: @io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04353 json.encode(&PrettyEncoder(wr))
Kevin Cantud47cb102012-08-30 23:39:56354}
355
Erick Tryzelaar8650c6f2012-12-18 03:31:04356/// Encodes a json value into a string
Erick Tryzelaar49d00b22012-09-24 16:55:42357pub fn to_pretty_str(json: &Json) -> ~str {
358 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40359}
360
Erick Tryzelaar49d00b22012-09-24 16:55:42361pub struct Parser {
Patrick Waltonb1c69982013-03-12 20:00:50362 priv rdr: @io::Reader,
Erick Tryzelaar49d00b22012-09-24 16:55:42363 priv mut ch: char,
364 priv mut line: uint,
365 priv mut col: uint,
366}
367
Erick Tryzelaar8650c6f2012-12-18 03:31:04368/// Decode a json value from an io::reader
Patrick Waltonb1c69982013-03-12 20:00:50369pub fn Parser(rdr: @io::Reader) -> Parser {
Erick Tryzelaar49d00b22012-09-24 16:55:42370 Parser {
371 rdr: rdr,
372 ch: rdr.read_char(),
Tim Chevalier90d06b82012-09-19 05:35:42373 line: 1,
374 col: 1,
Erick Tryzelaar49d00b22012-09-24 16:55:42375 }
376}
377
378pub impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09379 fn parse(&self) -> Result<Json, Error> {
Luqman Aden4cf51c22013-02-15 07:30:30380 match self.parse_value() {
381 Ok(value) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42382 // Skip trailing whitespaces.
383 self.parse_whitespace();
384 // Make sure there is no trailing characters.
385 if self.eof() {
Luqman Aden4cf51c22013-02-15 07:30:30386 Ok(value)
Erick Tryzelaar49d00b22012-09-24 16:55:42387 } else {
388 self.error(~"trailing characters")
389 }
390 }
Luqman Aden4cf51c22013-02-15 07:30:30391 Err(e) => Err(e)
Erick Tryzelaar49d00b22012-09-24 16:55:42392 }
393 }
394}
395
396priv impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09397 fn eof(&self) -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28398
Ben Striegel0fed29c2013-03-08 02:11:09399 fn bump(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32400 self.ch = self.rdr.read_char();
401
402 if self.ch == '\n' {
403 self.line += 1u;
404 self.col = 1u;
405 } else {
406 self.col += 1u;
407 }
Elly Jonesbd726262011-11-07 19:01:28408 }
409
Ben Striegel0fed29c2013-03-08 02:11:09410 fn next_char(&self) -> char {
Erick Tryzelaar012dec52012-02-26 00:39:32411 self.bump();
412 self.ch
Elly Jonesbd726262011-11-07 19:01:28413 }
414
Ben Striegel0fed29c2013-03-08 02:11:09415 fn error<T>(&self, msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42416 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28417 }
Elly Jonesbd726262011-11-07 19:01:28418
Ben Striegel0fed29c2013-03-08 02:11:09419 fn parse_value(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32420 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28421
Brian Andersonb3559362012-08-02 00:30:05422 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32423
Brian Andersonecaf9e32012-08-06 19:34:08424 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42425 'n' => self.parse_ident(~"ull", Null),
426 't' => self.parse_ident(~"rue", Boolean(true)),
427 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05428 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42429 '"' =>
Luqman Aden4cf51c22013-02-15 07:30:30430 match self.parse_str() {
431 Ok(s) => Ok(String(s)),
432 Err(e) => Err(e),
Erick Tryzelaar49d00b22012-09-24 16:55:42433 },
Brian Anderson025d8662012-08-04 02:59:04434 '[' => self.parse_list(),
435 '{' => self.parse_object(),
436 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32437 }
438 }
439
Ben Striegel0fed29c2013-03-08 02:11:09440 fn parse_whitespace(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32441 while char::is_whitespace(self.ch) { self.bump(); }
442 }
443
Ben Striegel0fed29c2013-03-08 02:11:09444 fn parse_ident(&self, ident: &str, value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07445 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32446 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30447 Ok(value)
Erick Tryzelaar012dec52012-02-26 00:39:32448 } else {
Michael Sullivan92743dc2012-07-14 05:57:48449 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32450 }
451 }
452
Ben Striegel0fed29c2013-03-08 02:11:09453 fn parse_number(&self) -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56454 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32455
456 if self.ch == '-' {
457 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00458 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28459 }
Elly Jonesbd726262011-11-07 19:01:28460
Brian Andersonecaf9e32012-08-06 19:34:08461 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31462 Ok(res) => res,
463 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32464 };
465
466 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08467 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31468 Ok(r) => res = r,
469 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28470 }
Elly Jonesbd726262011-11-07 19:01:28471 }
Erick Tryzelaar012dec52012-02-26 00:39:32472
473 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08474 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31475 Ok(r) => res = r,
476 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32477 }
478 }
479
Erick Tryzelaar49d00b22012-09-24 16:55:42480 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28481 }
482
Ben Striegel0fed29c2013-03-08 02:11:09483 fn parse_integer(&self) -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56484 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32485
Brian Andersonecaf9e32012-08-06 19:34:08486 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04487 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32488 self.bump();
489
490 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08491 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05492 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04493 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32494 }
495 }
Brian Anderson80c4f742012-09-02 01:38:05496 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32497 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08498 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05499 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32500 res *= 10f;
501 res += ((self.ch as int) - ('0' as int)) as float;
502
503 self.bump();
504 }
Brian Anderson025d8662012-08-04 02:59:04505 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32506 }
507 }
508 }
Brian Anderson025d8662012-08-04 02:59:04509 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32510 }
511
Brian Anderson0c6e4702012-08-26 23:54:31512 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28513 }
514
Ben Striegel0fed29c2013-03-08 02:11:09515 fn parse_decimal(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32516 self.bump();
517
518 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08519 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05520 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04521 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32522 }
523
Niko Matsakis6b358752012-03-14 18:03:56524 let mut res = res;
525 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32526 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08527 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05528 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00529 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32530 res += (((self.ch as int) - ('0' as int)) as float) * dec;
531
532 self.bump();
533 }
Brian Anderson025d8662012-08-04 02:59:04534 _ => break
Elly Jonesbd726262011-11-07 19:01:28535 }
Elly Jonesbd726262011-11-07 19:01:28536 }
Elly Jonesbd726262011-11-07 19:01:28537
Brian Anderson0c6e4702012-08-26 23:54:31538 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32539 }
540
Ben Striegel0fed29c2013-03-08 02:11:09541 fn parse_exponent(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32542 self.bump();
543
Niko Matsakis6b358752012-03-14 18:03:56544 let mut res = res;
545 let mut exp = 0u;
546 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32547
Brian Andersonecaf9e32012-08-06 19:34:08548 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04549 '+' => self.bump(),
550 '-' => { self.bump(); neg_exp = true; }
551 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32552 }
553
554 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08555 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05556 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04557 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32558 }
559
560 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08561 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05562 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32563 exp *= 10u;
564 exp += (self.ch as uint) - ('0' as uint);
565
566 self.bump();
567 }
Brian Anderson025d8662012-08-04 02:59:04568 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32569 }
570 }
571
572 let exp = float::pow_with_uint(10u, exp);
573 if neg_exp {
574 res /= exp;
575 } else {
576 res *= exp;
577 }
578
Brian Anderson0c6e4702012-08-26 23:54:31579 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32580 }
581
Ben Striegel0fed29c2013-03-08 02:11:09582 fn parse_str(&self) -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56583 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48584 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32585
586 while !self.eof() {
587 self.bump();
588
589 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08590 match self.ch {
Tim Chevalier5a8ba072012-10-11 21:12:50591 '"' => str::push_char(&mut res, '"'),
592 '\\' => str::push_char(&mut res, '\\'),
593 '/' => str::push_char(&mut res, '/'),
594 'b' => str::push_char(&mut res, '\x08'),
595 'f' => str::push_char(&mut res, '\x0c'),
596 'n' => str::push_char(&mut res, '\n'),
597 'r' => str::push_char(&mut res, '\r'),
598 't' => str::push_char(&mut res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04599 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32600 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56601 let mut i = 0u;
602 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32603 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08604 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05605 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10606 n = n * 16u + (self.ch as uint)
607 - ('0' as uint);
608 },
609 'a' | 'A' => n = n * 16u + 10u,
610 'b' | 'B' => n = n * 16u + 11u,
611 'c' | 'C' => n = n * 16u + 12u,
612 'd' | 'D' => n = n * 16u + 13u,
613 'e' | 'E' => n = n * 16u + 14u,
614 'f' | 'F' => n = n * 16u + 15u,
615 _ => return self.error(
616 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32617 }
Niko Matsakis6b358752012-03-14 18:03:56618 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32619 }
620
621 // Error out if we didn't parse 4 digits.
622 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10623 return self.error(
624 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32625 }
626
Tim Chevalier5a8ba072012-10-11 21:12:50627 str::push_char(&mut res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32628 }
Brian Anderson025d8662012-08-04 02:59:04629 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32630 }
631 escape = false;
632 } else if self.ch == '\\' {
633 escape = true;
634 } else {
635 if self.ch == '"' {
636 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42637 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32638 }
Tim Chevalier5a8ba072012-10-11 21:12:50639 str::push_char(&mut res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32640 }
641 }
642
Michael Sullivan92743dc2012-07-14 05:57:48643 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32644 }
645
Ben Striegel0fed29c2013-03-08 02:11:09646 fn parse_list(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32647 self.bump();
648 self.parse_whitespace();
649
Michael Sullivan98e161f2012-06-29 23:26:56650 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32651
652 if self.ch == ']' {
653 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30654 return Ok(List(values));
Erick Tryzelaar012dec52012-02-26 00:39:32655 }
656
Tim Chevalier35400e12012-03-11 04:34:17657 loop {
Luqman Aden4cf51c22013-02-15 07:30:30658 match self.parse_value() {
659 Ok(v) => values.push(v),
660 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32661 }
662
663 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17664 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05665 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17666 }
Erick Tryzelaar012dec52012-02-26 00:39:32667
Brian Andersonecaf9e32012-08-06 19:34:08668 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04669 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30670 ']' => { self.bump(); return Ok(List(values)); }
Brian Anderson025d8662012-08-04 02:59:04671 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32672 }
Tim Chevalier35400e12012-03-11 04:34:17673 };
Erick Tryzelaar012dec52012-02-26 00:39:32674 }
675
Ben Striegel0fed29c2013-03-08 02:11:09676 fn parse_object(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32677 self.bump();
678 self.parse_whitespace();
679
Daniel Micaycc148b52013-04-03 13:28:36680 let mut values = ~HashMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:32681
682 if self.ch == '}' {
683 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30684 return Ok(Object(values));
Erick Tryzelaar012dec52012-02-26 00:39:32685 }
686
687 while !self.eof() {
688 self.parse_whitespace();
689
690 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05691 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32692 }
693
Luqman Aden4cf51c22013-02-15 07:30:30694 let key = match self.parse_str() {
695 Ok(key) => key,
696 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32697 };
698
699 self.parse_whitespace();
700
701 if self.ch != ':' {
702 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05703 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32704 }
705 self.bump();
706
Luqman Aden4cf51c22013-02-15 07:30:30707 match self.parse_value() {
708 Ok(value) => { values.insert(key, value); }
709 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32710 }
711 self.parse_whitespace();
712
Brian Andersonecaf9e32012-08-06 19:34:08713 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04714 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30715 '}' => { self.bump(); return Ok(Object(values)); }
Brian Anderson025d8662012-08-04 02:59:04716 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32717 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05718 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32719 }
720 }
721 }
722
Brian Andersonb3559362012-08-02 00:30:05723 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28724 }
725}
726
Patrick Waltonb1c69982013-03-12 20:00:50727/// Decodes a json value from an @io::Reader
728pub fn from_reader(rdr: @io::Reader) -> Result<Json, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42729 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28730}
731
Erick Tryzelaar8650c6f2012-12-18 03:31:04732/// Decodes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42733pub fn from_str(s: &str) -> Result<Json, Error> {
734 do io::with_str_reader(s) |rdr| {
735 from_reader(rdr)
736 }
Erick Tryzelaar012dec52012-02-26 00:39:32737}
738
Erick Tryzelaard1a83e62013-03-29 16:04:35739pub struct Decoder {
740 priv mut stack: ~[Json],
Erick Tryzelaar49d00b22012-09-24 16:55:42741}
742
Erick Tryzelaar8650c6f2012-12-18 03:31:04743pub fn Decoder(json: Json) -> Decoder {
Erick Tryzelaard1a83e62013-03-29 16:04:35744 Decoder { stack: ~[json] }
Elly Jonesbd726262011-11-07 19:01:28745}
Brian Anderson6e27b272012-01-18 03:05:07746
Erick Tryzelaard1a83e62013-03-29 16:04:35747impl serialize::Decoder for Decoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42748 fn read_nil(&self) -> () {
749 debug!("read_nil");
Erick Tryzelaard1a83e62013-03-29 16:04:35750 match self.stack.pop() {
Erick Tryzelaar49d00b22012-09-24 16:55:42751 Null => (),
Erick Tryzelaard1a83e62013-03-29 16:04:35752 value => fail!(fmt!("not a null: %?", value))
Erick Tryzelaar49d00b22012-09-24 16:55:42753 }
754 }
755
756 fn read_u64(&self) -> u64 { self.read_float() as u64 }
757 fn read_u32(&self) -> u32 { self.read_float() as u32 }
758 fn read_u16(&self) -> u16 { self.read_float() as u16 }
759 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
760 fn read_uint(&self) -> uint { self.read_float() as uint }
761
762 fn read_i64(&self) -> i64 { self.read_float() as i64 }
763 fn read_i32(&self) -> i32 { self.read_float() as i32 }
764 fn read_i16(&self) -> i16 { self.read_float() as i16 }
765 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
766 fn read_int(&self) -> int { self.read_float() as int }
767
768 fn read_bool(&self) -> bool {
769 debug!("read_bool");
Erick Tryzelaard1a83e62013-03-29 16:04:35770 match self.stack.pop() {
Erick Tryzelaar49d00b22012-09-24 16:55:42771 Boolean(b) => b,
Erick Tryzelaard1a83e62013-03-29 16:04:35772 value => fail!(fmt!("not a boolean: %?", value))
Erick Tryzelaar49d00b22012-09-24 16:55:42773 }
774 }
775
776 fn read_f64(&self) -> f64 { self.read_float() as f64 }
777 fn read_f32(&self) -> f32 { self.read_float() as f32 }
778 fn read_float(&self) -> float {
779 debug!("read_float");
Erick Tryzelaard1a83e62013-03-29 16:04:35780 match self.stack.pop() {
Erick Tryzelaar49d00b22012-09-24 16:55:42781 Number(f) => f,
Erick Tryzelaard1a83e62013-03-29 16:04:35782 value => fail!(fmt!("not a number: %?", value))
Erick Tryzelaar49d00b22012-09-24 16:55:42783 }
784 }
785
Erick Tryzelaar81423a32012-09-27 04:35:13786 fn read_char(&self) -> char {
Marvin Löbelb9de2b52013-03-24 06:51:18787 let mut v = ~[];
Erick Tryzelaar8b43c622013-03-29 03:51:05788 for str::each_char(self.read_str()) |c| { v.push(c) }
Nick Desaulniers4445b382013-02-12 03:26:38789 if v.len() != 1 { fail!(~"string must have one character") }
Erick Tryzelaar81423a32012-09-27 04:35:13790 v[0]
791 }
792
Erick Tryzelaar8b43c622013-03-29 03:51:05793 fn read_str(&self) -> ~str {
794 debug!("read_str");
Erick Tryzelaard1a83e62013-03-29 16:04:35795 match self.stack.pop() {
796 String(s) => s,
797 json => fail!(fmt!("not a string: %?", json))
Erick Tryzelaar49d00b22012-09-24 16:55:42798 }
799 }
800
Patrick Waltond18f7852013-03-07 22:38:38801 fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42802 debug!("read_enum(%s)", name);
Erick Tryzelaar49d00b22012-09-24 16:55:42803 f()
804 }
805
Erick Tryzelaar4d6dcef2013-03-27 01:46:48806 fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
807 debug!("read_enum_variant(names=%?)", names);
Erick Tryzelaard1a83e62013-03-29 16:04:35808 let name = match self.stack.pop() {
809 String(s) => s,
810 List(list) => {
811 do vec::consume_reverse(list) |_i, v| {
812 self.stack.push(v);
813 }
814 match self.stack.pop() {
815 String(s) => s,
816 value => fail!(fmt!("invalid variant name: %?", value)),
817 }
818 }
Erick Tryzelaarc317d3f2013-03-27 06:15:14819 ref json => fail!(fmt!("invalid variant: %?", *json)),
Erick Tryzelaar4d6dcef2013-03-27 01:46:48820 };
Erick Tryzelaard1a83e62013-03-29 16:04:35821 let idx = match vec::position(names, |n| str::eq_slice(*n, name)) {
Erick Tryzelaar4d6dcef2013-03-27 01:46:48822 Some(idx) => idx,
823 None => fail!(fmt!("Unknown variant name: %?", name)),
824 };
825 f(idx)
826 }
827
Patrick Waltond18f7852013-03-07 22:38:38828 fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42829 debug!("read_enum_variant_arg(idx=%u)", idx);
Erick Tryzelaard1a83e62013-03-29 16:04:35830 f()
Erick Tryzelaar49d00b22012-09-24 16:55:42831 }
832
Erick Tryzelaar590bbce2013-03-29 04:34:47833 fn read_seq<T>(&self, f: &fn(uint) -> T) -> T {
834 debug!("read_seq()");
Erick Tryzelaard1a83e62013-03-29 16:04:35835 let len = match self.stack.pop() {
836 List(list) => {
837 let len = list.len();
838 do vec::consume_reverse(list) |_i, v| {
839 self.stack.push(v);
840 }
841 len
842 }
Nick Desaulniers4445b382013-02-12 03:26:38843 _ => fail!(~"not a list"),
Erick Tryzelaar81423a32012-09-27 04:35:13844 };
Erick Tryzelaarbdef3f12013-03-29 16:10:31845 f(len)
Erick Tryzelaar81423a32012-09-27 04:35:13846 }
847
Erick Tryzelaar590bbce2013-03-29 04:34:47848 fn read_seq_elt<T>(&self, idx: uint, f: &fn() -> T) -> T {
849 debug!("read_seq_elt(idx=%u)", idx);
Erick Tryzelaard1a83e62013-03-29 16:04:35850 f()
Erick Tryzelaar49d00b22012-09-24 16:55:42851 }
852
Erick Tryzelaard1a83e62013-03-29 16:04:35853 fn read_struct<T>(&self, name: &str, len: uint, f: &fn() -> T) -> T {
854 debug!("read_struct(name=%s, len=%u)", name, len);
Erick Tryzelaar81423a32012-09-27 04:35:13855 let value = f();
Erick Tryzelaard1a83e62013-03-29 16:04:35856 self.stack.pop();
Luqman Aden4cf51c22013-02-15 07:30:30857 value
Erick Tryzelaar81423a32012-09-27 04:35:13858 }
859
Patrick Waltond18f7852013-03-07 22:38:38860 fn read_field<T>(&self, name: &str, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar90b36582013-03-29 05:19:43861 debug!("read_field(%s, idx=%u)", name, idx);
Erick Tryzelaard1a83e62013-03-29 16:04:35862 match self.stack.pop() {
863 Object(obj) => {
864 let mut obj = obj;
865 let value = match obj.pop(&name.to_owned()) {
Nick Desaulniers4445b382013-02-12 03:26:38866 None => fail!(fmt!("no such field: %s", name)),
Erick Tryzelaar49d00b22012-09-24 16:55:42867 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34868 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42869 f()
870 }
Erick Tryzelaard1a83e62013-03-29 16:04:35871 };
872 self.stack.push(Object(obj));
873 value
Erick Tryzelaar49d00b22012-09-24 16:55:42874 }
Erick Tryzelaard1a83e62013-03-29 16:04:35875 value => fail!(fmt!("not an object: %?", value))
Erick Tryzelaar49d00b22012-09-24 16:55:42876 }
877 }
878
Erick Tryzelaarb05e1482013-03-28 20:11:14879 fn read_option<T>(&self, f: &fn(bool) -> T) -> T {
Erick Tryzelaard1a83e62013-03-29 16:04:35880 match self.stack.pop() {
881 Null => f(false),
882 value => { self.stack.push(value); f(true) }
Erick Tryzelaar478e4492013-03-26 22:26:05883 }
884 }
Erick Tryzelaard1a83e62013-03-29 16:04:35885
886 fn read_map<T>(&self, f: &fn(uint) -> T) -> T {
887 debug!("read_map()");
888 let len = match self.stack.pop() {
889 Object(obj) => {
890 let mut obj = obj;
891 let len = obj.len();
892 do obj.consume |key, value| {
893 self.stack.push(value);
894 self.stack.push(String(key));
895 }
896 len
897 }
898 json => fail!(fmt!("not an object: %?", json)),
899 };
900 f(len)
901 }
902
903 fn read_map_elt_key<T>(&self, idx: uint, f: &fn() -> T) -> T {
904 debug!("read_map_elt_key(idx=%u)", idx);
905 f()
906 }
907
908 fn read_map_elt_val<T>(&self, idx: uint, f: &fn() -> T) -> T {
909 debug!("read_map_elt_val(idx=%u)", idx);
910 f()
911 }
Erick Tryzelaar49d00b22012-09-24 16:55:42912}
913
Patrick Walton91436882013-02-14 19:47:00914impl Eq for Json {
Patrick Waltonc1084092013-03-22 04:34:30915 fn eq(&self, other: &Json) -> bool {
Tim Chevalier3e7da962013-01-11 04:09:16916 match (self) {
917 &Number(f0) =>
918 match other { &Number(f1) => f0 == f1, _ => false },
919 &String(ref s0) =>
920 match other { &String(ref s1) => s0 == s1, _ => false },
921 &Boolean(b0) =>
922 match other { &Boolean(b1) => b0 == b1, _ => false },
923 &Null =>
924 match other { &Null => true, _ => false },
925 &List(ref v0) =>
926 match other { &List(ref v1) => v0 == v1, _ => false },
927 &Object(ref d0) => {
928 match other {
929 &Object(ref d1) => {
Patrick Walton318e5342012-11-15 02:59:30930 if d0.len() == d1.len() {
931 let mut equal = true;
Daniel Micay9599cc82013-02-08 02:03:13932 for d0.each |&(k, v0)| {
Daniel Micayee0a8c62013-01-23 16:47:43933 match d1.find(k) {
Patrick Walton318e5342012-11-15 02:59:30934 Some(v1) if v0 == v1 => { },
935 _ => { equal = false; break }
936 }
937 };
938 equal
939 } else {
940 false
941 }
942 }
943 _ => false
944 }
945 }
946 }
947 }
Patrick Waltonc1084092013-03-22 04:34:30948 fn ne(&self, other: &Json) -> bool { !self.eq(other) }
Erick Tryzelaar49d00b22012-09-24 16:55:42949}
950
Patrick Walton22b87572012-09-08 01:53:14951/// Test if two json values are less than one another
Patrick Walton91436882013-02-14 19:47:00952impl Ord for Json {
Patrick Waltonc1084092013-03-22 04:34:30953 fn lt(&self, other: &Json) -> bool {
Patrick Walton318e5342012-11-15 02:59:30954 match (*self) {
955 Number(f0) => {
956 match *other {
957 Number(f1) => f0 < f1,
958 String(_) | Boolean(_) | List(_) | Object(_) |
959 Null => true
960 }
961 }
962
963 String(ref s0) => {
964 match *other {
965 Number(_) => false,
966 String(ref s1) => s0 < s1,
967 Boolean(_) | List(_) | Object(_) | Null => true
968 }
969 }
970
971 Boolean(b0) => {
972 match *other {
973 Number(_) | String(_) => false,
974 Boolean(b1) => b0 < b1,
975 List(_) | Object(_) | Null => true
976 }
977 }
978
Patrick Walton98fdcb02012-12-08 03:34:57979 List(ref l0) => {
Patrick Walton318e5342012-11-15 02:59:30980 match *other {
981 Number(_) | String(_) | Boolean(_) => false,
Patrick Walton98fdcb02012-12-08 03:34:57982 List(ref l1) => (*l0) < (*l1),
Patrick Walton318e5342012-11-15 02:59:30983 Object(_) | Null => true
984 }
985 }
986
987 Object(ref d0) => {
988 match *other {
989 Number(_) | String(_) | Boolean(_) | List(_) => false,
990 Object(ref d1) => {
991 unsafe {
992 let mut d0_flat = ~[];
993 let mut d1_flat = ~[];
994
Tim Chevalier3e7da962013-01-11 04:09:16995 // FIXME #4430: this is horribly inefficient...
Daniel Micay9599cc82013-02-08 02:03:13996 for d0.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:30997 d0_flat.push((@copy *k, @copy *v));
998 }
999 d0_flat.qsort();
1000
Daniel Micay9599cc82013-02-08 02:03:131001 for d1.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301002 d1_flat.push((@copy *k, @copy *v));
1003 }
1004 d1_flat.qsort();
1005
1006 d0_flat < d1_flat
1007 }
1008 }
1009 Null => true
1010 }
1011 }
1012
1013 Null => {
1014 match *other {
1015 Number(_) | String(_) | Boolean(_) | List(_) |
1016 Object(_) =>
1017 false,
1018 Null => true
1019 }
1020 }
1021 }
1022 }
Patrick Waltonc1084092013-03-22 04:34:301023 fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) }
1024 fn ge(&self, other: &Json) -> bool { !(*self).lt(other) }
1025 fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) }
Patrick Walton22b87572012-09-08 01:53:141026}
1027
Ben Striegel0fed29c2013-03-08 02:11:091028trait ToJson { fn to_json(&self) -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:321029
Patrick Walton91436882013-02-14 19:47:001030impl ToJson for Json {
Ben Striegel0fed29c2013-03-08 02:11:091031 fn to_json(&self) -> Json { copy *self }
Erick Tryzelaared5af702012-05-28 19:10:321032}
1033
Patrick Walton91436882013-02-14 19:47:001034impl ToJson for @Json {
Ben Striegel0fed29c2013-03-08 02:11:091035 fn to_json(&self) -> Json { (**self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:541036}
1037
Patrick Walton91436882013-02-14 19:47:001038impl ToJson for int {
Ben Striegel0fed29c2013-03-08 02:11:091039 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541040}
1041
Patrick Walton91436882013-02-14 19:47:001042impl ToJson for i8 {
Ben Striegel0fed29c2013-03-08 02:11:091043 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321044}
1045
Patrick Walton91436882013-02-14 19:47:001046impl ToJson for i16 {
Ben Striegel0fed29c2013-03-08 02:11:091047 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321048}
1049
Patrick Walton91436882013-02-14 19:47:001050impl ToJson for i32 {
Ben Striegel0fed29c2013-03-08 02:11:091051 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321052}
1053
Patrick Walton91436882013-02-14 19:47:001054impl ToJson for i64 {
Ben Striegel0fed29c2013-03-08 02:11:091055 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321056}
1057
Patrick Walton91436882013-02-14 19:47:001058impl ToJson for uint {
Ben Striegel0fed29c2013-03-08 02:11:091059 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541060}
1061
Patrick Walton91436882013-02-14 19:47:001062impl ToJson for u8 {
Ben Striegel0fed29c2013-03-08 02:11:091063 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321064}
1065
Patrick Walton91436882013-02-14 19:47:001066impl ToJson for u16 {
Ben Striegel0fed29c2013-03-08 02:11:091067 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321068}
1069
Patrick Walton91436882013-02-14 19:47:001070impl ToJson for u32 {
Ben Striegel0fed29c2013-03-08 02:11:091071 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321072}
1073
Patrick Walton91436882013-02-14 19:47:001074impl ToJson for u64 {
Ben Striegel0fed29c2013-03-08 02:11:091075 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321076}
1077
Patrick Walton91436882013-02-14 19:47:001078impl ToJson for float {
Ben Striegel0fed29c2013-03-08 02:11:091079 fn to_json(&self) -> Json { Number(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321080}
1081
Patrick Walton91436882013-02-14 19:47:001082impl ToJson for f32 {
Ben Striegel0fed29c2013-03-08 02:11:091083 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321084}
1085
Patrick Walton91436882013-02-14 19:47:001086impl ToJson for f64 {
Ben Striegel0fed29c2013-03-08 02:11:091087 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321088}
1089
Patrick Walton91436882013-02-14 19:47:001090impl ToJson for () {
Ben Striegel0fed29c2013-03-08 02:11:091091 fn to_json(&self) -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321092}
1093
Patrick Walton91436882013-02-14 19:47:001094impl ToJson for bool {
Ben Striegel0fed29c2013-03-08 02:11:091095 fn to_json(&self) -> Json { Boolean(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321096}
1097
Patrick Walton91436882013-02-14 19:47:001098impl ToJson for ~str {
Ben Striegel0fed29c2013-03-08 02:11:091099 fn to_json(&self) -> Json { String(copy *self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511100}
1101
Patrick Walton91436882013-02-14 19:47:001102impl ToJson for @~str {
Ben Striegel0fed29c2013-03-08 02:11:091103 fn to_json(&self) -> Json { String(copy **self) }
Erick Tryzelaared5af702012-05-28 19:10:321104}
1105
Patrick Waltonbf2a2252013-02-21 01:07:171106impl<A:ToJson,B:ToJson> ToJson for (A, B) {
Ben Striegel0fed29c2013-03-08 02:11:091107 fn to_json(&self) -> Json {
1108 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181109 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421110 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561111 }
1112 }
Erick Tryzelaared5af702012-05-28 19:10:321113 }
1114}
1115
Patrick Waltonbf2a2252013-02-21 01:07:171116impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
Ben Striegel0fed29c2013-03-08 02:11:091117 fn to_json(&self) -> Json {
1118 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181119 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421120 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561121 }
1122 }
Erick Tryzelaared5af702012-05-28 19:10:321123 }
1124}
1125
Patrick Waltonbf2a2252013-02-21 01:07:171126impl<A:ToJson> ToJson for ~[A] {
Ben Striegel0fed29c2013-03-08 02:11:091127 fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321128}
1129
Daniel Micaycc148b52013-04-03 13:28:361130impl<A:ToJson + Copy> ToJson for HashMap<~str, A> {
Ben Striegel0fed29c2013-03-08 02:11:091131 fn to_json(&self) -> Json {
Daniel Micaycc148b52013-04-03 13:28:361132 let mut d = HashMap::new();
Daniel Micay9599cc82013-02-08 02:03:131133 for self.each |&(key, value)| {
Erick Tryzelaar49d00b22012-09-24 16:55:421134 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321135 }
Erick Tryzelaar49d00b22012-09-24 16:55:421136 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321137 }
1138}
1139
Patrick Waltonbf2a2252013-02-21 01:07:171140impl<A:ToJson> ToJson for Option<A> {
Ben Striegel0fed29c2013-03-08 02:11:091141 fn to_json(&self) -> Json {
1142 match *self {
Ben Striegela605fd02012-08-11 14:08:421143 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181144 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321145 }
1146 }
1147}
1148
Patrick Walton91436882013-02-14 19:47:001149impl to_str::ToStr for Json {
Patrick Waltonc1084092013-03-22 04:34:301150 fn to_str(&self) -> ~str { to_str(self) }
Erick Tryzelaared5af702012-05-28 19:10:321151}
1152
Patrick Walton91436882013-02-14 19:47:001153impl to_str::ToStr for Error {
Patrick Waltonc1084092013-03-22 04:34:301154 fn to_str(&self) -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521155 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381156 }
1157}
1158
Brian Anderson6e27b272012-01-18 03:05:071159#[cfg(test)]
1160mod tests {
Erick Tryzelaarb2908632013-03-27 00:46:291161 use super::*;
1162
Patrick Walton2db3abd2013-01-09 03:37:251163 use core::prelude::*;
Daniel Micaycc148b52013-04-03 13:28:361164 use core::hashmap::HashMap;
John Clementsf91160b2013-02-08 01:06:261165
Erick Tryzelaarb10b8c32013-03-27 07:13:011166 use std::serialize::Decodable;
1167
Erick Tryzelaar9bbf3842013-03-30 18:08:571168 #[auto_encode]
1169 #[auto_decode]
1170 #[deriving(Eq)]
1171 enum Animal {
1172 Dog,
1173 Frog(~str, int)
1174 }
1175
Erick Tryzelaar5b7d6082013-03-30 20:31:031176 #[auto_encode]
1177 #[auto_decode]
1178 #[deriving(Eq)]
1179 struct Inner {
1180 a: (),
1181 b: uint,
1182 c: ~[~str],
1183 }
1184
1185 #[auto_encode]
1186 #[auto_decode]
1187 #[deriving(Eq)]
1188 struct Outer {
1189 inner: ~[Inner],
1190 }
1191
Erick Tryzelaar49d00b22012-09-24 16:55:421192 fn mk_object(items: &[(~str, Json)]) -> Json {
Daniel Micaycc148b52013-04-03 13:28:361193 let mut d = ~HashMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:321194
Erick Tryzelaar49d00b22012-09-24 16:55:421195 for items.each |item| {
1196 match *item {
Luqman Aden4cf51c22013-02-15 07:30:301197 (copy key, copy value) => { d.insert(key, value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421198 }
Erick Tryzelaar012dec52012-02-26 00:39:321199 };
1200
Luqman Aden4cf51c22013-02-15 07:30:301201 Object(d)
Brian Anderson6e27b272012-01-18 03:05:071202 }
1203
1204 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321205 fn test_write_null() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001206 assert_eq!(to_str(&Null), ~"null");
Erick Tryzelaar9bbf3842013-03-30 18:08:571207 assert_eq!(to_pretty_str(&Null), ~"null");
Brian Anderson6e27b272012-01-18 03:05:071208 }
1209
Erick Tryzelaar9bbf3842013-03-30 18:08:571210
Brian Anderson6e27b272012-01-18 03:05:071211 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421212 fn test_write_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001213 assert_eq!(to_str(&Number(3f)), ~"3");
Erick Tryzelaar9bbf3842013-03-30 18:08:571214 assert_eq!(to_pretty_str(&Number(3f)), ~"3");
1215
Erick Tryzelaar6cf99fa2013-03-27 00:23:001216 assert_eq!(to_str(&Number(3.1f)), ~"3.1");
Erick Tryzelaar9bbf3842013-03-30 18:08:571217 assert_eq!(to_pretty_str(&Number(3.1f)), ~"3.1");
1218
Erick Tryzelaar6cf99fa2013-03-27 00:23:001219 assert_eq!(to_str(&Number(-1.5f)), ~"-1.5");
Erick Tryzelaar9bbf3842013-03-30 18:08:571220 assert_eq!(to_pretty_str(&Number(-1.5f)), ~"-1.5");
1221
Erick Tryzelaar6cf99fa2013-03-27 00:23:001222 assert_eq!(to_str(&Number(0.5f)), ~"0.5");
Erick Tryzelaar9bbf3842013-03-30 18:08:571223 assert_eq!(to_pretty_str(&Number(0.5f)), ~"0.5");
Brian Anderson6e27b272012-01-18 03:05:071224 }
1225
1226 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321227 fn test_write_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001228 assert_eq!(to_str(&String(~"")), ~"\"\"");
Erick Tryzelaar9bbf3842013-03-30 18:08:571229 assert_eq!(to_pretty_str(&String(~"")), ~"\"\"");
1230
Erick Tryzelaar6cf99fa2013-03-27 00:23:001231 assert_eq!(to_str(&String(~"foo")), ~"\"foo\"");
Erick Tryzelaar9bbf3842013-03-30 18:08:571232 assert_eq!(to_pretty_str(&String(~"foo")), ~"\"foo\"");
Brian Anderson6e27b272012-01-18 03:05:071233 }
1234
1235 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321236 fn test_write_bool() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001237 assert_eq!(to_str(&Boolean(true)), ~"true");
Erick Tryzelaar9bbf3842013-03-30 18:08:571238 assert_eq!(to_pretty_str(&Boolean(true)), ~"true");
1239
Erick Tryzelaar6cf99fa2013-03-27 00:23:001240 assert_eq!(to_str(&Boolean(false)), ~"false");
Erick Tryzelaar9bbf3842013-03-30 18:08:571241 assert_eq!(to_pretty_str(&Boolean(false)), ~"false");
Brian Anderson6e27b272012-01-18 03:05:071242 }
1243
1244 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321245 fn test_write_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001246 assert_eq!(to_str(&List(~[])), ~"[]");
Erick Tryzelaarc9188c82013-03-27 00:34:491247 assert_eq!(to_pretty_str(&List(~[])), ~"[]");
Erick Tryzelaar9bbf3842013-03-30 18:08:571248
1249 assert_eq!(to_str(&List(~[Boolean(true)])), ~"[true]");
Erick Tryzelaarc9188c82013-03-27 00:34:491250 assert_eq!(
1251 to_pretty_str(&List(~[Boolean(true)])),
1252 ~"\
1253 [\n \
1254 true\n\
1255 ]"
1256 );
Erick Tryzelaar9bbf3842013-03-30 18:08:571257
1258 assert_eq!(to_str(&List(~[
1259 Boolean(false),
1260 Null,
1261 List(~[String(~"foo\nbar"), Number(3.5f)])
1262 ])), ~"[false,null,[\"foo\\nbar\",3.5]]");
Erick Tryzelaarc9188c82013-03-27 00:34:491263 assert_eq!(
1264 to_pretty_str(&List(~[
1265 Boolean(false),
1266 Null,
1267 List(~[String(~"foo\nbar"), Number(3.5f)])
1268 ])),
1269 ~"\
1270 [\n \
1271 false,\n \
1272 null,\n \
1273 [\n \
1274 \"foo\\nbar\",\n \
1275 3.5\n \
1276 ]\n\
1277 ]"
1278 );
1279 }
1280
1281 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421282 fn test_write_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001283 assert_eq!(to_str(&mk_object(~[])), ~"{}");
Erick Tryzelaar9bbf3842013-03-30 18:08:571284 assert_eq!(to_pretty_str(&mk_object(~[])), ~"{}");
1285
Erick Tryzelaar6cf99fa2013-03-27 00:23:001286 assert_eq!(
1287 to_str(&mk_object(~[(~"a", Boolean(true))])),
1288 ~"{\"a\":true}"
1289 );
Erick Tryzelaarc9188c82013-03-27 00:34:491290 assert_eq!(
Erick Tryzelaar9bbf3842013-03-30 18:08:571291 to_pretty_str(&mk_object(~[(~"a", Boolean(true))])),
1292 ~"\
1293 {\n \
1294 \"a\": true\n\
1295 }"
1296 );
1297
1298 assert_eq!(
Erick Tryzelaarc9188c82013-03-27 00:34:491299 to_str(&mk_object(~[
1300 (~"b", List(~[
1301 mk_object(~[(~"c", String(~"\x0c\r"))]),
1302 mk_object(~[(~"d", String(~""))])
1303 ]))
1304 ])),
1305 ~"{\
1306 \"b\":[\
1307 {\"c\":\"\\f\\r\"},\
1308 {\"d\":\"\"}\
1309 ]\
1310 }"
1311 );
Erick Tryzelaarc9188c82013-03-27 00:34:491312 assert_eq!(
1313 to_pretty_str(&mk_object(~[
1314 (~"b", List(~[
1315 mk_object(~[(~"c", String(~"\x0c\r"))]),
1316 mk_object(~[(~"d", String(~""))])
1317 ]))
1318 ])),
1319 ~"\
1320 {\n \
1321 \"b\": [\n \
1322 {\n \
1323 \"c\": \"\\f\\r\"\n \
1324 },\n \
1325 {\n \
1326 \"d\": \"\"\n \
1327 }\n \
1328 ]\n\
1329 }"
1330 );
Erick Tryzelaar9bbf3842013-03-30 18:08:571331
Erick Tryzelaarc9188c82013-03-27 00:34:491332 let a = mk_object(~[
1333 (~"a", Boolean(true)),
1334 (~"b", List(~[
1335 mk_object(~[(~"c", String(~"\x0c\r"))]),
1336 mk_object(~[(~"d", String(~""))])
1337 ]))
1338 ]);
Erick Tryzelaar9bbf3842013-03-30 18:08:571339
Erick Tryzelaarc9188c82013-03-27 00:34:491340 // We can't compare the strings directly because the object fields be
1341 // printed in a different order.
Erick Tryzelaar9bbf3842013-03-30 18:08:571342 assert_eq!(copy a, from_str(to_str(&a)).unwrap());
1343 assert_eq!(copy a, from_str(to_pretty_str(&a)).unwrap());
Erick Tryzelaarc9188c82013-03-27 00:34:491344 }
1345
1346 #[test]
Erick Tryzelaar9bbf3842013-03-30 18:08:571347 fn test_write_enum() {
Erick Tryzelaarc9188c82013-03-27 00:34:491348 let animal = Dog;
Erick Tryzelaarc9188c82013-03-27 00:34:491349 assert_eq!(
Erick Tryzelaar9bbf3842013-03-30 18:08:571350 do io::with_str_writer |wr| {
1351 let encoder = Encoder(wr);
1352 animal.encode(&encoder);
1353 },
1354 ~"\"Dog\""
1355 );
1356 assert_eq!(
1357 do io::with_str_writer |wr| {
1358 let encoder = PrettyEncoder(wr);
1359 animal.encode(&encoder);
1360 },
1361 ~"\"Dog\""
1362 );
1363
1364 let animal = Frog(~"Henry", 349);
1365 assert_eq!(
1366 do io::with_str_writer |wr| {
1367 let encoder = Encoder(wr);
1368 animal.encode(&encoder);
1369 },
1370 ~"[\"Frog\",\"Henry\",349]"
1371 );
1372 assert_eq!(
1373 do io::with_str_writer |wr| {
1374 let encoder = PrettyEncoder(wr);
1375 animal.encode(&encoder);
1376 },
Erick Tryzelaarc9188c82013-03-27 00:34:491377 ~"\
1378 [\n \
1379 \"Frog\",\n \
Erick Tryzelaar4d995e62013-03-27 07:14:521380 \"Henry\",\n \
1381 349\n\
Erick Tryzelaarc9188c82013-03-27 00:34:491382 ]"
1383 );
John Clementsc952c042013-02-08 23:36:401384 }
1385
1386 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001387 fn test_write_some() {
1388 let value = Some(~"jodhpurs");
1389 let s = do io::with_str_writer |wr| {
1390 let encoder = Encoder(wr);
1391 value.encode(&encoder);
1392 };
1393 assert_eq!(s, ~"\"jodhpurs\"");
John Clementsc952c042013-02-08 23:36:401394
Erick Tryzelaarc9188c82013-03-27 00:34:491395 let value = Some(~"jodhpurs");
1396 let s = do io::with_str_writer |wr| {
1397 let encoder = PrettyEncoder(wr);
1398 value.encode(&encoder);
1399 };
1400 assert_eq!(s, ~"\"jodhpurs\"");
1401 }
1402
1403 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001404 fn test_write_none() {
1405 let value: Option<~str> = None;
1406 let s = do io::with_str_writer |wr| {
1407 let encoder = Encoder(wr);
1408 value.encode(&encoder);
1409 };
1410 assert_eq!(s, ~"null");
John Clementsf91160b2013-02-08 01:06:261411
Erick Tryzelaarc9188c82013-03-27 00:34:491412 let s = do io::with_str_writer |wr| {
1413 let encoder = Encoder(wr);
1414 value.encode(&encoder);
1415 };
1416 assert_eq!(s, ~"null");
1417 }
1418
1419 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321420 fn test_trailing_characters() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001421 assert_eq!(from_str(~"nulla"),
Patrick Waltond7e74b52013-03-06 21:58:021422 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001423 assert_eq!(from_str(~"truea"),
Patrick Waltond7e74b52013-03-06 21:58:021424 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001425 assert_eq!(from_str(~"falsea"),
Patrick Waltond7e74b52013-03-06 21:58:021426 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001427 assert_eq!(from_str(~"1a"),
Patrick Waltond7e74b52013-03-06 21:58:021428 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001429 assert_eq!(from_str(~"[]a"),
Patrick Waltond7e74b52013-03-06 21:58:021430 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001431 assert_eq!(from_str(~"{}a"),
Patrick Waltond7e74b52013-03-06 21:58:021432 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar012dec52012-02-26 00:39:321433 }
1434
1435 #[test]
1436 fn test_read_identifiers() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001437 assert_eq!(from_str(~"n"),
Patrick Waltond7e74b52013-03-06 21:58:021438 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001439 assert_eq!(from_str(~"nul"),
Patrick Waltond7e74b52013-03-06 21:58:021440 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321441
Erick Tryzelaar6cf99fa2013-03-27 00:23:001442 assert_eq!(from_str(~"t"),
Patrick Waltond7e74b52013-03-06 21:58:021443 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001444 assert_eq!(from_str(~"truz"),
Patrick Waltond7e74b52013-03-06 21:58:021445 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321446
Erick Tryzelaar6cf99fa2013-03-27 00:23:001447 assert_eq!(from_str(~"f"),
Patrick Waltond7e74b52013-03-06 21:58:021448 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001449 assert_eq!(from_str(~"faz"),
Patrick Waltond7e74b52013-03-06 21:58:021450 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321451
Erick Tryzelaar6cf99fa2013-03-27 00:23:001452 assert_eq!(from_str(~"null"), Ok(Null));
1453 assert_eq!(from_str(~"true"), Ok(Boolean(true)));
1454 assert_eq!(from_str(~"false"), Ok(Boolean(false)));
1455 assert_eq!(from_str(~" null "), Ok(Null));
1456 assert_eq!(from_str(~" true "), Ok(Boolean(true)));
1457 assert_eq!(from_str(~" false "), Ok(Boolean(false)));
Erick Tryzelaar012dec52012-02-26 00:39:321458 }
1459
1460 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031461 fn test_decode_identifiers() {
1462 let v: () = Decodable::decode(&Decoder(from_str(~"null").unwrap()));
1463 assert_eq!(v, ());
1464
1465 let v: bool = Decodable::decode(&Decoder(from_str(~"true").unwrap()));
1466 assert_eq!(v, true);
1467
1468 let v: bool = Decodable::decode(&Decoder(from_str(~"false").unwrap()));
1469 assert_eq!(v, false);
1470 }
1471
1472 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421473 fn test_read_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001474 assert_eq!(from_str(~"+"),
Patrick Waltond7e74b52013-03-06 21:58:021475 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001476 assert_eq!(from_str(~"."),
Patrick Waltond7e74b52013-03-06 21:58:021477 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321478
Erick Tryzelaar6cf99fa2013-03-27 00:23:001479 assert_eq!(from_str(~"-"),
Patrick Waltond7e74b52013-03-06 21:58:021480 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001481 assert_eq!(from_str(~"00"),
Patrick Waltond7e74b52013-03-06 21:58:021482 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001483 assert_eq!(from_str(~"1."),
Patrick Waltond7e74b52013-03-06 21:58:021484 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001485 assert_eq!(from_str(~"1e"),
Patrick Waltond7e74b52013-03-06 21:58:021486 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001487 assert_eq!(from_str(~"1e+"),
Patrick Waltond7e74b52013-03-06 21:58:021488 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"}));
Erick Tryzelaar012dec52012-02-26 00:39:321489
Erick Tryzelaar6cf99fa2013-03-27 00:23:001490 assert_eq!(from_str(~"3"), Ok(Number(3f)));
1491 assert_eq!(from_str(~"3.1"), Ok(Number(3.1f)));
1492 assert_eq!(from_str(~"-1.2"), Ok(Number(-1.2f)));
1493 assert_eq!(from_str(~"0.4"), Ok(Number(0.4f)));
1494 assert_eq!(from_str(~"0.4e5"), Ok(Number(0.4e5f)));
1495 assert_eq!(from_str(~"0.4e+15"), Ok(Number(0.4e15f)));
1496 assert_eq!(from_str(~"0.4e-01"), Ok(Number(0.4e-01f)));
1497 assert_eq!(from_str(~" 3 "), Ok(Number(3f)));
Erick Tryzelaar012dec52012-02-26 00:39:321498 }
1499
1500 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031501 fn test_decode_numbers() {
1502 let v: float = Decodable::decode(&Decoder(from_str(~"3").unwrap()));
1503 assert_eq!(v, 3f);
1504
1505 let v: float = Decodable::decode(&Decoder(from_str(~"3.1").unwrap()));
1506 assert_eq!(v, 3.1f);
1507
1508 let v: float = Decodable::decode(&Decoder(from_str(~"-1.2").unwrap()));
1509 assert_eq!(v, -1.2f);
1510
1511 let v: float = Decodable::decode(&Decoder(from_str(~"0.4").unwrap()));
1512 assert_eq!(v, 0.4f);
1513
1514 let v: float = Decodable::decode(&Decoder(from_str(~"0.4e5").unwrap()));
1515 assert_eq!(v, 0.4e5f);
1516
1517 let v: float = Decodable::decode(&Decoder(from_str(~"0.4e15").unwrap()));
1518 assert_eq!(v, 0.4e15f);
1519
1520 let v: float = Decodable::decode(&Decoder(from_str(~"0.4e-01").unwrap()));
1521 assert_eq!(v, 0.4e-01f);
1522 }
1523
1524 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321525 fn test_read_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001526 assert_eq!(from_str(~"\""),
Patrick Waltond7e74b52013-03-06 21:58:021527 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"
1528 }));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001529 assert_eq!(from_str(~"\"lol"),
Patrick Waltond7e74b52013-03-06 21:58:021530 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"
1531 }));
Erick Tryzelaar012dec52012-02-26 00:39:321532
Erick Tryzelaar6cf99fa2013-03-27 00:23:001533 assert_eq!(from_str(~"\"\""), Ok(String(~"")));
1534 assert_eq!(from_str(~"\"foo\""), Ok(String(~"foo")));
1535 assert_eq!(from_str(~"\"\\\"\""), Ok(String(~"\"")));
1536 assert_eq!(from_str(~"\"\\b\""), Ok(String(~"\x08")));
1537 assert_eq!(from_str(~"\"\\n\""), Ok(String(~"\n")));
1538 assert_eq!(from_str(~"\"\\r\""), Ok(String(~"\r")));
1539 assert_eq!(from_str(~"\"\\t\""), Ok(String(~"\t")));
1540 assert_eq!(from_str(~" \"foo\" "), Ok(String(~"foo")));
Erick Tryzelaar5b7d6082013-03-30 20:31:031541 assert_eq!(from_str(~"\"\\u12ab\""), Ok(String(~"\u12ab")));
1542 assert_eq!(from_str(~"\"\\uAB12\""), Ok(String(~"\uAB12")));
Erick Tryzelaar012dec52012-02-26 00:39:321543 }
1544
1545 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031546 fn test_decode_str() {
1547 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\"").unwrap()));
1548 assert_eq!(v, ~"");
1549
1550 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"foo\"").unwrap()));
1551 assert_eq!(v, ~"foo");
1552
1553 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\\"\"").unwrap()));
1554 assert_eq!(v, ~"\"");
1555
1556 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\b\"").unwrap()));
1557 assert_eq!(v, ~"\x08");
1558
1559 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\n\"").unwrap()));
1560 assert_eq!(v, ~"\n");
1561
1562 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\r\"").unwrap()));
1563 assert_eq!(v, ~"\r");
1564
1565 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\t\"").unwrap()));
1566 assert_eq!(v, ~"\t");
1567
1568 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\u12ab\"").unwrap()));
1569 assert_eq!(v, ~"\u12ab");
1570
1571 let v: ~str = Decodable::decode(&Decoder(from_str(~"\"\\uAB12\"").unwrap()));
1572 assert_eq!(v, ~"\uAB12");
Kevin Cantucf386182012-08-31 04:03:191573 }
1574
1575 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321576 fn test_read_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001577 assert_eq!(from_str(~"["),
Patrick Waltond7e74b52013-03-06 21:58:021578 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001579 assert_eq!(from_str(~"[1"),
Patrick Waltond7e74b52013-03-06 21:58:021580 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001581 assert_eq!(from_str(~"[1,"),
Patrick Waltond7e74b52013-03-06 21:58:021582 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001583 assert_eq!(from_str(~"[1,]"),
Patrick Waltond7e74b52013-03-06 21:58:021584 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001585 assert_eq!(from_str(~"[6 7]"),
Patrick Waltond7e74b52013-03-06 21:58:021586 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"}));
Erick Tryzelaar012dec52012-02-26 00:39:321587
Erick Tryzelaar6cf99fa2013-03-27 00:23:001588 assert_eq!(from_str(~"[]"), Ok(List(~[])));
1589 assert_eq!(from_str(~"[ ]"), Ok(List(~[])));
1590 assert_eq!(from_str(~"[true]"), Ok(List(~[Boolean(true)])));
1591 assert_eq!(from_str(~"[ false ]"), Ok(List(~[Boolean(false)])));
1592 assert_eq!(from_str(~"[null]"), Ok(List(~[Null])));
1593 assert_eq!(from_str(~"[3, 1]"),
Patrick Waltond7e74b52013-03-06 21:58:021594 Ok(List(~[Number(3f), Number(1f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001595 assert_eq!(from_str(~"\n[3, 2]\n"),
Patrick Waltond7e74b52013-03-06 21:58:021596 Ok(List(~[Number(3f), Number(2f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001597 assert_eq!(from_str(~"[2, [4, 1]]"),
Patrick Waltond7e74b52013-03-06 21:58:021598 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])])));
Erick Tryzelaar012dec52012-02-26 00:39:321599 }
1600
1601 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031602 fn test_decode_list() {
1603 let v: ~[()] = Decodable::decode(&Decoder(from_str(~"[]").unwrap()));
1604 assert_eq!(v, ~[]);
1605
1606 let v: ~[()] = Decodable::decode(&Decoder(from_str(~"[null]").unwrap()));
1607 assert_eq!(v, ~[()]);
1608
1609
1610 let v: ~[bool] = Decodable::decode(&Decoder(from_str(~"[true]").unwrap()));
1611 assert_eq!(v, ~[true]);
1612
1613 let v: ~[bool] = Decodable::decode(&Decoder(from_str(~"[true]").unwrap()));
1614 assert_eq!(v, ~[true]);
1615
1616 let v: ~[int] = Decodable::decode(&Decoder(from_str(~"[3, 1]").unwrap()));
1617 assert_eq!(v, ~[3, 1]);
1618
1619 let v: ~[~[uint]] = Decodable::decode(&Decoder(from_str(~"[[3], [1, 2]]").unwrap()));
1620 assert_eq!(v, ~[~[3], ~[1, 2]]);
1621 }
1622
1623 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421624 fn test_read_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001625 assert_eq!(from_str(~"{"),
Patrick Waltond7e74b52013-03-06 21:58:021626 Err(Error {
1627 line: 1u,
1628 col: 2u,
1629 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001630 assert_eq!(from_str(~"{ "),
Patrick Waltond7e74b52013-03-06 21:58:021631 Err(Error {
1632 line: 1u,
1633 col: 3u,
1634 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001635 assert_eq!(from_str(~"{1"),
Patrick Waltond7e74b52013-03-06 21:58:021636 Err(Error {
1637 line: 1u,
1638 col: 2u,
1639 msg: @~"key must be a string"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001640 assert_eq!(from_str(~"{ \"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021641 Err(Error {
1642 line: 1u,
1643 col: 6u,
1644 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001645 assert_eq!(from_str(~"{\"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021646 Err(Error {
1647 line: 1u,
1648 col: 5u,
1649 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001650 assert_eq!(from_str(~"{\"a\" "),
Patrick Waltond7e74b52013-03-06 21:58:021651 Err(Error {
1652 line: 1u,
1653 col: 6u,
1654 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321655
Erick Tryzelaar6cf99fa2013-03-27 00:23:001656 assert_eq!(from_str(~"{\"a\" 1"),
Patrick Waltond7e74b52013-03-06 21:58:021657 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001658 assert_eq!(from_str(~"{\"a\":"),
Patrick Waltond7e74b52013-03-06 21:58:021659 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001660 assert_eq!(from_str(~"{\"a\":1"),
Patrick Waltond7e74b52013-03-06 21:58:021661 Err(Error {
1662 line: 1u,
1663 col: 7u,
1664 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001665 assert_eq!(from_str(~"{\"a\":1 1"),
Patrick Waltond7e74b52013-03-06 21:58:021666 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001667 assert_eq!(from_str(~"{\"a\":1,"),
Patrick Waltond7e74b52013-03-06 21:58:021668 Err(Error {
1669 line: 1u,
1670 col: 8u,
1671 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321672
Erick Tryzelaar6cf99fa2013-03-27 00:23:001673 assert_eq!(result::unwrap(from_str(~"{}")), mk_object(~[]));
1674 assert_eq!(result::unwrap(from_str(~"{\"a\": 3}")),
Patrick Waltond7e74b52013-03-06 21:58:021675 mk_object(~[(~"a", Number(3.0f))]));
Erick Tryzelaar012dec52012-02-26 00:39:321676
Erick Tryzelaar6cf99fa2013-03-27 00:23:001677 assert_eq!(result::unwrap(from_str(
1678 ~"{ \"a\": null, \"b\" : true }")),
Erick Tryzelaar49d00b22012-09-24 16:55:421679 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421680 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021681 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001682 assert_eq!(result::unwrap(
1683 from_str(~"\n{ \"a\": null, \"b\" : true }\n")),
Erick Tryzelaar49d00b22012-09-24 16:55:421684 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421685 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021686 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001687 assert_eq!(result::unwrap(from_str(
1688 ~"{\"a\" : 1.0 ,\"b\": [ true ]}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421689 mk_object(~[
1690 (~"a", Number(1.0)),
1691 (~"b", List(~[Boolean(true)]))
Patrick Waltond7e74b52013-03-06 21:58:021692 ]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001693 assert_eq!(result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481694 ~"{" +
1695 ~"\"a\": 1.0, " +
1696 ~"\"b\": [" +
1697 ~"true," +
1698 ~"\"foo\\nbar\", " +
1699 ~"{ \"c\": {\"d\": null} } " +
1700 ~"]" +
Erick Tryzelaar6cf99fa2013-03-27 00:23:001701 ~"}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421702 mk_object(~[
1703 (~"a", Number(1.0f)),
1704 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421705 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421706 String(~"foo\nbar"),
1707 mk_object(~[
1708 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561709 ])
1710 ]))
Patrick Waltond7e74b52013-03-06 21:58:021711 ]));
Erick Tryzelaar012dec52012-02-26 00:39:321712 }
1713
1714 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031715 fn test_decode_struct() {
1716 let s = ~"{
1717 \"inner\": [
1718 { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
1719 ]
1720 }";
1721 let v: Outer = Decodable::decode(&Decoder(from_str(s).unwrap()));
1722 assert_eq!(
1723 v,
1724 Outer {
1725 inner: ~[
1726 Inner { a: (), b: 2, c: ~[~"abc", ~"xyz"] }
1727 ]
1728 }
1729 );
Erick Tryzelaarb10b8c32013-03-27 07:13:011730 }
1731
1732 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031733 fn test_decode_option() {
1734 let decoder = Decoder(from_str(~"null").unwrap());
1735 let value: Option<~str> = Decodable::decode(&decoder);
1736 assert_eq!(value, None);
1737
Erick Tryzelaarb10b8c32013-03-27 07:13:011738 let decoder = Decoder(from_str(~"\"jodhpurs\"").unwrap());
1739 let value: Option<~str> = Decodable::decode(&decoder);
1740 assert_eq!(value, Some(~"jodhpurs"));
1741 }
1742
1743 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031744 fn test_decode_enum() {
Erick Tryzelaar4e9a63f2013-03-27 00:42:011745 let decoder = Decoder(from_str(~"\"Dog\"").unwrap());
1746 let value: Animal = Decodable::decode(&decoder);
1747 assert_eq!(value, Dog);
Erick Tryzelaar4e9a63f2013-03-27 00:42:011748
Erick Tryzelaar4e9a63f2013-03-27 00:42:011749 let decoder = Decoder(from_str(~"[\"Frog\",\"Henry\",349]").unwrap());
1750 let value: Animal = Decodable::decode(&decoder);
1751 assert_eq!(value, Frog(~"Henry", 349));
1752 }
1753
1754 #[test]
Erick Tryzelaar5b7d6082013-03-30 20:31:031755 fn test_decode_map() {
Erick Tryzelaard1a83e62013-03-29 16:04:351756 let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
1757 let decoder = Decoder(from_str(s).unwrap());
Daniel Micaycc148b52013-04-03 13:28:361758 let mut map: HashMap<~str, Animal> = Decodable::decode(&decoder);
Erick Tryzelaard1a83e62013-03-29 16:04:351759
Erick Tryzelaarbdef3f12013-03-29 16:10:311760 assert_eq!(map.pop(&~"a"), Some(Dog));
1761 assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349)));
Erick Tryzelaard1a83e62013-03-29 16:04:351762 }
1763
1764 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321765 fn test_multiline_errors() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001766 assert_eq!(from_str(~"{\n \"foo\":\n \"bar\""),
Patrick Waltond7e74b52013-03-06 21:58:021767 Err(Error {
1768 line: 3u,
1769 col: 8u,
1770 msg: @~"EOF while parsing object"}));
Brian Anderson6e27b272012-01-18 03:05:071771 }
1772}