blob: 968c6d9e58bb5f0f1f011932b09104c0aec22039 [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};
19use core::hashmap::linear::LinearMap;
20
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 Micay7f0fa142013-01-23 22:06:3236pub type Object = LinearMap<~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 Tryzelaar81423a32012-09-27 04:35:13108 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
109
110 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
111 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
112 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
113
Patrick Waltond18f7852013-03-07 22:38:38114 fn emit_borrowed(&self, f: &fn()) { f() }
115 fn emit_owned(&self, f: &fn()) { f() }
116 fn emit_managed(&self, f: &fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42117
Patrick Waltond18f7852013-03-07 22:38:38118 fn emit_enum(&self, _name: &str, f: &fn()) {
John Clementsfe823742013-02-07 01:19:11119 f()
120 }
John Clements394f8ee2013-02-07 01:23:41121
Erick Tryzelaar4d995e62013-03-27 07:14:52122 fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) {
Erick Tryzelaar478e4492013-03-26 22:26:05123 // enums are encoded as strings or vectors:
Erick Tryzelaar4d995e62013-03-27 07:14:52124 // Bunny => "Bunny"
John Clementsc952c042013-02-08 23:36:40125 // Kangaroo(34,"William") => ["Kangaroo",[34,"William"]]
John Clements7736ed62013-02-09 02:58:33126
Erick Tryzelaar478e4492013-03-26 22:26:05127 if cnt == 0 {
Erick Tryzelaar4d995e62013-03-27 07:14:52128 self.wr.write_str(escape_str(name));
John Clementsc952c042013-02-08 23:36:40129 } else {
130 self.wr.write_char('[');
131 self.wr.write_str(escape_str(name));
132 self.wr.write_char(',');
John Clementsc952c042013-02-08 23:36:40133 f();
134 self.wr.write_char(']');
John Clementsc952c042013-02-08 23:36:40135 }
Erick Tryzelaar49d00b22012-09-24 16:55:42136 }
John Clementsf91160b2013-02-08 01:06:26137
Patrick Waltond18f7852013-03-07 22:38:38138 fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) {
John Clementsc952c042013-02-08 23:36:40139 if (idx != 0) {self.wr.write_char(',');}
John Clementsfe823742013-02-07 01:19:11140 f();
Erick Tryzelaar49d00b22012-09-24 16:55:42141 }
142
Patrick Waltond18f7852013-03-07 22:38:38143 fn emit_borrowed_vec(&self, _len: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42144 self.wr.write_char('[');
145 f();
146 self.wr.write_char(']');
147 }
John Clements7736ed62013-02-09 02:58:33148
Patrick Waltond18f7852013-03-07 22:38:38149 fn emit_owned_vec(&self, len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13150 self.emit_borrowed_vec(len, f)
151 }
Patrick Waltond18f7852013-03-07 22:38:38152 fn emit_managed_vec(&self, len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13153 self.emit_borrowed_vec(len, f)
154 }
Patrick Waltond18f7852013-03-07 22:38:38155 fn emit_vec_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42156 if idx != 0 { self.wr.write_char(','); }
157 f()
158 }
159
Patrick Waltond18f7852013-03-07 22:38:38160 fn emit_rec(&self, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42161 self.wr.write_char('{');
162 f();
163 self.wr.write_char('}');
164 }
Patrick Waltond18f7852013-03-07 22:38:38165 fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13166 self.wr.write_char('{');
167 f();
168 self.wr.write_char('}');
169 }
Patrick Waltond18f7852013-03-07 22:38:38170 fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42171 if idx != 0 { self.wr.write_char(','); }
172 self.wr.write_str(escape_str(name));
173 self.wr.write_char(':');
174 f();
175 }
Erick Tryzelaar81423a32012-09-27 04:35:13176
Patrick Waltond18f7852013-03-07 22:38:38177 fn emit_tup(&self, len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13178 self.emit_borrowed_vec(len, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42179 }
Patrick Waltond18f7852013-03-07 22:38:38180 fn emit_tup_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42181 self.emit_vec_elt(idx, f)
182 }
Erick Tryzelaar478e4492013-03-26 22:26:05183
184 fn emit_option(&self, f: &fn()) { f(); }
185 fn emit_option_none(&self) { self.emit_nil(); }
186 fn emit_option_some(&self, f: &fn()) { f(); }
Erick Tryzelaar49d00b22012-09-24 16:55:42187}
188
Erick Tryzelaar8650c6f2012-12-18 03:31:04189pub struct PrettyEncoder {
Patrick Waltonb1c69982013-03-12 20:00:50190 priv wr: @io::Writer,
Erick Tryzelaar49d00b22012-09-24 16:55:42191 priv mut indent: uint,
192}
193
Patrick Waltonb1c69982013-03-12 20:00:50194pub fn PrettyEncoder(wr: @io::Writer) -> PrettyEncoder {
Erick Tryzelaar8650c6f2012-12-18 03:31:04195 PrettyEncoder { wr: wr, indent: 0 }
Erick Tryzelaar49d00b22012-09-24 16:55:42196}
197
Patrick Walton07c3f5c2013-02-27 01:12:00198impl serialize::Encoder for PrettyEncoder {
Erick Tryzelaar49d00b22012-09-24 16:55:42199 fn emit_nil(&self) { self.wr.write_str("null") }
200
201 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
202 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
203 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
204 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
205 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
206
207 fn emit_int(&self, v: int) { self.emit_float(v as float); }
208 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
209 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
210 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
211 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
212
213 fn emit_bool(&self, v: bool) {
214 if v {
215 self.wr.write_str("true");
216 } else {
217 self.wr.write_str("false");
218 }
219 }
220
221 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
222 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
223 fn emit_float(&self, v: float) {
Marvin Löbela612e492013-01-27 02:28:39224 self.wr.write_str(float::to_str_digits(v, 6u));
Erick Tryzelaar49d00b22012-09-24 16:55:42225 }
226
Erick Tryzelaar81423a32012-09-27 04:35:13227 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
228
229 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
230 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
231 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
232
Patrick Waltond18f7852013-03-07 22:38:38233 fn emit_borrowed(&self, f: &fn()) { f() }
234 fn emit_owned(&self, f: &fn()) { f() }
235 fn emit_managed(&self, f: &fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42236
Erick Tryzelaarc9188c82013-03-27 00:34:49237 fn emit_enum(&self, _name: &str, f: &fn()) { f() }
238 fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) {
Erick Tryzelaar478e4492013-03-26 22:26:05239 if cnt == 0 {
Erick Tryzelaar4d995e62013-03-27 07:14:52240 self.wr.write_str(escape_str(name));
Erick Tryzelaar49d00b22012-09-24 16:55:42241 } else {
Erick Tryzelaarc9188c82013-03-27 00:34:49242 self.wr.write_char('[');
243 self.indent += 2;
244 self.wr.write_char('\n');
245 self.wr.write_str(spaces(self.indent));
246 self.wr.write_str(escape_str(name));
Erick Tryzelaar4d995e62013-03-27 07:14:52247 self.wr.write_str(",\n");
248 f();
249 self.wr.write_char('\n');
Erick Tryzelaarc9188c82013-03-27 00:34:49250 self.indent -= 2;
Erick Tryzelaar4d995e62013-03-27 07:14:52251 self.wr.write_str(spaces(self.indent));
Erick Tryzelaarc9188c82013-03-27 00:34:49252 self.wr.write_char(']');
Erick Tryzelaar49d00b22012-09-24 16:55:42253 }
254 }
Erick Tryzelaarc9188c82013-03-27 00:34:49255 fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) {
256 if idx != 0 {
257 self.wr.write_str(",\n");
258 }
259 self.wr.write_str(spaces(self.indent));
Erick Tryzelaar49d00b22012-09-24 16:55:42260 f()
261 }
262
Erick Tryzelaarc9188c82013-03-27 00:34:49263 fn emit_borrowed_vec(&self, len: uint, f: &fn()) {
264 if len == 0 {
265 self.wr.write_str("[]");
266 } else {
267 self.wr.write_char('[');
268 self.indent += 2;
269 f();
270 self.wr.write_char('\n');
271 self.indent -= 2;
272 self.wr.write_str(spaces(self.indent));
273 self.wr.write_char(']');
274 }
Erick Tryzelaar49d00b22012-09-24 16:55:42275 }
Patrick Waltond18f7852013-03-07 22:38:38276 fn emit_owned_vec(&self, len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13277 self.emit_borrowed_vec(len, f)
278 }
Patrick Waltond18f7852013-03-07 22:38:38279 fn emit_managed_vec(&self, len: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13280 self.emit_borrowed_vec(len, f)
281 }
Patrick Waltond18f7852013-03-07 22:38:38282 fn emit_vec_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42283 if idx == 0 {
284 self.wr.write_char('\n');
285 } else {
286 self.wr.write_str(",\n");
287 }
288 self.wr.write_str(spaces(self.indent));
289 f()
290 }
291
Patrick Waltond18f7852013-03-07 22:38:38292 fn emit_rec(&self, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42293 self.wr.write_char('{');
294 self.indent += 2;
295 f();
Erick Tryzelaarc9188c82013-03-27 00:34:49296 self.wr.write_char('\n');
Erick Tryzelaar49d00b22012-09-24 16:55:42297 self.indent -= 2;
Erick Tryzelaarc9188c82013-03-27 00:34:49298 self.wr.write_str(spaces(self.indent));
Erick Tryzelaar49d00b22012-09-24 16:55:42299 self.wr.write_char('}');
300 }
Erick Tryzelaarc9188c82013-03-27 00:34:49301 fn emit_struct(&self, _name: &str, len: uint, f: &fn()) {
302 if len == 0 {
303 self.wr.write_str("{}");
304 } else {
305 self.emit_rec(f)
306 }
Erick Tryzelaar81423a32012-09-27 04:35:13307 }
Patrick Waltond18f7852013-03-07 22:38:38308 fn emit_field(&self, name: &str, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42309 if idx == 0 {
310 self.wr.write_char('\n');
311 } else {
312 self.wr.write_str(",\n");
313 }
314 self.wr.write_str(spaces(self.indent));
315 self.wr.write_str(escape_str(name));
316 self.wr.write_str(": ");
317 f();
318 }
Patrick Waltond18f7852013-03-07 22:38:38319 fn emit_tup(&self, sz: uint, f: &fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13320 self.emit_borrowed_vec(sz, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42321 }
Patrick Waltond18f7852013-03-07 22:38:38322 fn emit_tup_elt(&self, idx: uint, f: &fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42323 self.emit_vec_elt(idx, f)
324 }
Erick Tryzelaar478e4492013-03-26 22:26:05325
326 fn emit_option(&self, f: &fn()) { f(); }
327 fn emit_option_none(&self) { self.emit_nil(); }
328 fn emit_option_some(&self, f: &fn()) { f(); }
Erick Tryzelaar49d00b22012-09-24 16:55:42329}
330
Patrick Walton07c3f5c2013-02-27 01:12:00331impl<S:serialize::Encoder> serialize::Encodable<S> for Json {
Erick Tryzelaar8650c6f2012-12-18 03:31:04332 fn encode(&self, s: &S) {
Erick Tryzelaarab89b5c2012-10-13 16:11:33333 match *self {
Erick Tryzelaar8650c6f2012-12-18 03:31:04334 Number(v) => v.encode(s),
335 String(ref v) => v.encode(s),
336 Boolean(v) => v.encode(s),
337 List(ref v) => v.encode(s),
Erick Tryzelaarab89b5c2012-10-13 16:11:33338 Object(ref v) => {
339 do s.emit_rec || {
340 let mut idx = 0;
Daniel Micay9599cc82013-02-08 02:03:13341 for v.each |&(key, value)| {
Erick Tryzelaarab89b5c2012-10-13 16:11:33342 do s.emit_field(*key, idx) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04343 value.encode(s);
Erick Tryzelaarab89b5c2012-10-13 16:11:33344 }
345 idx += 1;
346 }
347 }
348 },
349 Null => s.emit_nil(),
350 }
351 }
352}
353
Erick Tryzelaar8650c6f2012-12-18 03:31:04354/// Encodes a json value into a io::writer
Patrick Waltonb1c69982013-03-12 20:00:50355pub fn to_writer(wr: @io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04356 json.encode(&Encoder(wr))
Erick Tryzelaar49d00b22012-09-24 16:55:42357}
358
Erick Tryzelaar8650c6f2012-12-18 03:31:04359/// Encodes a json value into a string
Patrick Waltonc1084092013-03-22 04:34:30360pub fn to_str(json: &Json) -> ~str {
Patrick Walton54b2cad2013-01-23 19:43:58361 unsafe {
362 // ugh, should be safe
363 io::with_str_writer(|wr| to_writer(wr, json))
364 }
Elly Jonesbd726262011-11-07 19:01:28365}
366
Erick Tryzelaar8650c6f2012-12-18 03:31:04367/// Encodes a json value into a io::writer
Patrick Waltonb1c69982013-03-12 20:00:50368pub fn to_pretty_writer(wr: @io::Writer, json: &Json) {
Erick Tryzelaar8650c6f2012-12-18 03:31:04369 json.encode(&PrettyEncoder(wr))
Kevin Cantud47cb102012-08-30 23:39:56370}
371
Erick Tryzelaar8650c6f2012-12-18 03:31:04372/// Encodes a json value into a string
Erick Tryzelaar49d00b22012-09-24 16:55:42373pub fn to_pretty_str(json: &Json) -> ~str {
374 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40375}
376
Erick Tryzelaar49d00b22012-09-24 16:55:42377pub struct Parser {
Patrick Waltonb1c69982013-03-12 20:00:50378 priv rdr: @io::Reader,
Erick Tryzelaar49d00b22012-09-24 16:55:42379 priv mut ch: char,
380 priv mut line: uint,
381 priv mut col: uint,
382}
383
Erick Tryzelaar8650c6f2012-12-18 03:31:04384/// Decode a json value from an io::reader
Patrick Waltonb1c69982013-03-12 20:00:50385pub fn Parser(rdr: @io::Reader) -> Parser {
Erick Tryzelaar49d00b22012-09-24 16:55:42386 Parser {
387 rdr: rdr,
388 ch: rdr.read_char(),
Tim Chevalier90d06b82012-09-19 05:35:42389 line: 1,
390 col: 1,
Erick Tryzelaar49d00b22012-09-24 16:55:42391 }
392}
393
394pub impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09395 fn parse(&self) -> Result<Json, Error> {
Luqman Aden4cf51c22013-02-15 07:30:30396 match self.parse_value() {
397 Ok(value) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42398 // Skip trailing whitespaces.
399 self.parse_whitespace();
400 // Make sure there is no trailing characters.
401 if self.eof() {
Luqman Aden4cf51c22013-02-15 07:30:30402 Ok(value)
Erick Tryzelaar49d00b22012-09-24 16:55:42403 } else {
404 self.error(~"trailing characters")
405 }
406 }
Luqman Aden4cf51c22013-02-15 07:30:30407 Err(e) => Err(e)
Erick Tryzelaar49d00b22012-09-24 16:55:42408 }
409 }
410}
411
412priv impl Parser {
Ben Striegel0fed29c2013-03-08 02:11:09413 fn eof(&self) -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28414
Ben Striegel0fed29c2013-03-08 02:11:09415 fn bump(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32416 self.ch = self.rdr.read_char();
417
418 if self.ch == '\n' {
419 self.line += 1u;
420 self.col = 1u;
421 } else {
422 self.col += 1u;
423 }
Elly Jonesbd726262011-11-07 19:01:28424 }
425
Ben Striegel0fed29c2013-03-08 02:11:09426 fn next_char(&self) -> char {
Erick Tryzelaar012dec52012-02-26 00:39:32427 self.bump();
428 self.ch
Elly Jonesbd726262011-11-07 19:01:28429 }
430
Ben Striegel0fed29c2013-03-08 02:11:09431 fn error<T>(&self, msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42432 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28433 }
Elly Jonesbd726262011-11-07 19:01:28434
Ben Striegel0fed29c2013-03-08 02:11:09435 fn parse_value(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32436 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28437
Brian Andersonb3559362012-08-02 00:30:05438 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32439
Brian Andersonecaf9e32012-08-06 19:34:08440 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42441 'n' => self.parse_ident(~"ull", Null),
442 't' => self.parse_ident(~"rue", Boolean(true)),
443 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05444 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42445 '"' =>
Luqman Aden4cf51c22013-02-15 07:30:30446 match self.parse_str() {
447 Ok(s) => Ok(String(s)),
448 Err(e) => Err(e),
Erick Tryzelaar49d00b22012-09-24 16:55:42449 },
Brian Anderson025d8662012-08-04 02:59:04450 '[' => self.parse_list(),
451 '{' => self.parse_object(),
452 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32453 }
454 }
455
Ben Striegel0fed29c2013-03-08 02:11:09456 fn parse_whitespace(&self) {
Erick Tryzelaar012dec52012-02-26 00:39:32457 while char::is_whitespace(self.ch) { self.bump(); }
458 }
459
Ben Striegel0fed29c2013-03-08 02:11:09460 fn parse_ident(&self, ident: &str, value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07461 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32462 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30463 Ok(value)
Erick Tryzelaar012dec52012-02-26 00:39:32464 } else {
Michael Sullivan92743dc2012-07-14 05:57:48465 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32466 }
467 }
468
Ben Striegel0fed29c2013-03-08 02:11:09469 fn parse_number(&self) -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56470 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32471
472 if self.ch == '-' {
473 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00474 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28475 }
Elly Jonesbd726262011-11-07 19:01:28476
Brian Andersonecaf9e32012-08-06 19:34:08477 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31478 Ok(res) => res,
479 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32480 };
481
482 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08483 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31484 Ok(r) => res = r,
485 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28486 }
Elly Jonesbd726262011-11-07 19:01:28487 }
Erick Tryzelaar012dec52012-02-26 00:39:32488
489 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08490 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31491 Ok(r) => res = r,
492 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32493 }
494 }
495
Erick Tryzelaar49d00b22012-09-24 16:55:42496 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28497 }
498
Ben Striegel0fed29c2013-03-08 02:11:09499 fn parse_integer(&self) -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56500 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32501
Brian Andersonecaf9e32012-08-06 19:34:08502 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04503 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32504 self.bump();
505
506 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08507 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05508 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04509 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32510 }
511 }
Brian Anderson80c4f742012-09-02 01:38:05512 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32513 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08514 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05515 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32516 res *= 10f;
517 res += ((self.ch as int) - ('0' as int)) as float;
518
519 self.bump();
520 }
Brian Anderson025d8662012-08-04 02:59:04521 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32522 }
523 }
524 }
Brian Anderson025d8662012-08-04 02:59:04525 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32526 }
527
Brian Anderson0c6e4702012-08-26 23:54:31528 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28529 }
530
Ben Striegel0fed29c2013-03-08 02:11:09531 fn parse_decimal(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32532 self.bump();
533
534 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08535 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05536 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04537 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32538 }
539
Niko Matsakis6b358752012-03-14 18:03:56540 let mut res = res;
541 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32542 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08543 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05544 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00545 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32546 res += (((self.ch as int) - ('0' as int)) as float) * dec;
547
548 self.bump();
549 }
Brian Anderson025d8662012-08-04 02:59:04550 _ => break
Elly Jonesbd726262011-11-07 19:01:28551 }
Elly Jonesbd726262011-11-07 19:01:28552 }
Elly Jonesbd726262011-11-07 19:01:28553
Brian Anderson0c6e4702012-08-26 23:54:31554 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32555 }
556
Ben Striegel0fed29c2013-03-08 02:11:09557 fn parse_exponent(&self, res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32558 self.bump();
559
Niko Matsakis6b358752012-03-14 18:03:56560 let mut res = res;
561 let mut exp = 0u;
562 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32563
Brian Andersonecaf9e32012-08-06 19:34:08564 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04565 '+' => self.bump(),
566 '-' => { self.bump(); neg_exp = true; }
567 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32568 }
569
570 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08571 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05572 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04573 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32574 }
575
576 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08577 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05578 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32579 exp *= 10u;
580 exp += (self.ch as uint) - ('0' as uint);
581
582 self.bump();
583 }
Brian Anderson025d8662012-08-04 02:59:04584 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32585 }
586 }
587
588 let exp = float::pow_with_uint(10u, exp);
589 if neg_exp {
590 res /= exp;
591 } else {
592 res *= exp;
593 }
594
Brian Anderson0c6e4702012-08-26 23:54:31595 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32596 }
597
Ben Striegel0fed29c2013-03-08 02:11:09598 fn parse_str(&self) -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56599 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48600 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32601
602 while !self.eof() {
603 self.bump();
604
605 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08606 match self.ch {
Tim Chevalier5a8ba072012-10-11 21:12:50607 '"' => str::push_char(&mut res, '"'),
608 '\\' => str::push_char(&mut res, '\\'),
609 '/' => str::push_char(&mut res, '/'),
610 'b' => str::push_char(&mut res, '\x08'),
611 'f' => str::push_char(&mut res, '\x0c'),
612 'n' => str::push_char(&mut res, '\n'),
613 'r' => str::push_char(&mut res, '\r'),
614 't' => str::push_char(&mut res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04615 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32616 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56617 let mut i = 0u;
618 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32619 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08620 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05621 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10622 n = n * 16u + (self.ch as uint)
623 - ('0' as uint);
624 },
625 'a' | 'A' => n = n * 16u + 10u,
626 'b' | 'B' => n = n * 16u + 11u,
627 'c' | 'C' => n = n * 16u + 12u,
628 'd' | 'D' => n = n * 16u + 13u,
629 'e' | 'E' => n = n * 16u + 14u,
630 'f' | 'F' => n = n * 16u + 15u,
631 _ => return self.error(
632 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32633 }
Niko Matsakis6b358752012-03-14 18:03:56634 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32635 }
636
637 // Error out if we didn't parse 4 digits.
638 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10639 return self.error(
640 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32641 }
642
Tim Chevalier5a8ba072012-10-11 21:12:50643 str::push_char(&mut res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32644 }
Brian Anderson025d8662012-08-04 02:59:04645 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32646 }
647 escape = false;
648 } else if self.ch == '\\' {
649 escape = true;
650 } else {
651 if self.ch == '"' {
652 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42653 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32654 }
Tim Chevalier5a8ba072012-10-11 21:12:50655 str::push_char(&mut res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32656 }
657 }
658
Michael Sullivan92743dc2012-07-14 05:57:48659 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32660 }
661
Ben Striegel0fed29c2013-03-08 02:11:09662 fn parse_list(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32663 self.bump();
664 self.parse_whitespace();
665
Michael Sullivan98e161f2012-06-29 23:26:56666 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32667
668 if self.ch == ']' {
669 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30670 return Ok(List(values));
Erick Tryzelaar012dec52012-02-26 00:39:32671 }
672
Tim Chevalier35400e12012-03-11 04:34:17673 loop {
Luqman Aden4cf51c22013-02-15 07:30:30674 match self.parse_value() {
675 Ok(v) => values.push(v),
676 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32677 }
678
679 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17680 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05681 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17682 }
Erick Tryzelaar012dec52012-02-26 00:39:32683
Brian Andersonecaf9e32012-08-06 19:34:08684 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04685 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30686 ']' => { self.bump(); return Ok(List(values)); }
Brian Anderson025d8662012-08-04 02:59:04687 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32688 }
Tim Chevalier35400e12012-03-11 04:34:17689 };
Erick Tryzelaar012dec52012-02-26 00:39:32690 }
691
Ben Striegel0fed29c2013-03-08 02:11:09692 fn parse_object(&self) -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32693 self.bump();
694 self.parse_whitespace();
695
Daniel Micay7f0fa142013-01-23 22:06:32696 let mut values = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:32697
698 if self.ch == '}' {
699 self.bump();
Luqman Aden4cf51c22013-02-15 07:30:30700 return Ok(Object(values));
Erick Tryzelaar012dec52012-02-26 00:39:32701 }
702
703 while !self.eof() {
704 self.parse_whitespace();
705
706 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05707 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32708 }
709
Luqman Aden4cf51c22013-02-15 07:30:30710 let key = match self.parse_str() {
711 Ok(key) => key,
712 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32713 };
714
715 self.parse_whitespace();
716
717 if self.ch != ':' {
718 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05719 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32720 }
721 self.bump();
722
Luqman Aden4cf51c22013-02-15 07:30:30723 match self.parse_value() {
724 Ok(value) => { values.insert(key, value); }
725 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32726 }
727 self.parse_whitespace();
728
Brian Andersonecaf9e32012-08-06 19:34:08729 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04730 ',' => self.bump(),
Luqman Aden4cf51c22013-02-15 07:30:30731 '}' => { self.bump(); return Ok(Object(values)); }
Brian Anderson025d8662012-08-04 02:59:04732 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32733 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05734 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32735 }
736 }
737 }
738
Brian Andersonb3559362012-08-02 00:30:05739 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28740 }
741}
742
Patrick Waltonb1c69982013-03-12 20:00:50743/// Decodes a json value from an @io::Reader
744pub fn from_reader(rdr: @io::Reader) -> Result<Json, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42745 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28746}
747
Erick Tryzelaar8650c6f2012-12-18 03:31:04748/// Decodes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42749pub fn from_str(s: &str) -> Result<Json, Error> {
750 do io::with_str_reader(s) |rdr| {
751 from_reader(rdr)
752 }
Erick Tryzelaar012dec52012-02-26 00:39:32753}
754
Patrick Walton8b56a832013-03-25 20:21:04755pub struct Decoder<'self> {
Erick Tryzelaar49d00b22012-09-24 16:55:42756 priv json: Json,
Patrick Walton352c0702013-03-14 18:22:51757 priv mut stack: ~[&'self Json],
Erick Tryzelaar49d00b22012-09-24 16:55:42758}
759
Erick Tryzelaar8650c6f2012-12-18 03:31:04760pub fn Decoder(json: Json) -> Decoder {
Luqman Aden4cf51c22013-02-15 07:30:30761 Decoder { json: json, stack: ~[] }
Elly Jonesbd726262011-11-07 19:01:28762}
Brian Anderson6e27b272012-01-18 03:05:07763
Patrick Walton8b56a832013-03-25 20:21:04764priv impl<'self> Decoder<'self> {
Patrick Walton352c0702013-03-14 18:22:51765 fn peek(&self) -> &'self Json {
Patrick Waltone78f2e22013-03-16 18:11:31766 if vec::uniq_len(&const self.stack) == 0 {
767 self.stack.push(&self.json);
768 }
769 self.stack[vec::uniq_len(&const self.stack) - 1]
Erick Tryzelaar49d00b22012-09-24 16:55:42770 }
771
Patrick Walton352c0702013-03-14 18:22:51772 fn pop(&self) -> &'self Json {
Patrick Waltone78f2e22013-03-16 18:11:31773 if vec::uniq_len(&const self.stack) == 0 {
774 self.stack.push(&self.json);
775 }
Niko Matsakis21519bc2012-09-28 05:20:47776 self.stack.pop()
Erick Tryzelaar49d00b22012-09-24 16:55:42777 }
778}
779
Patrick Walton8b56a832013-03-25 20:21:04780impl<'self> serialize::Decoder for Decoder<'self> {
Erick Tryzelaar49d00b22012-09-24 16:55:42781 fn read_nil(&self) -> () {
782 debug!("read_nil");
783 match *self.pop() {
784 Null => (),
Nick Desaulniers4445b382013-02-12 03:26:38785 _ => fail!(~"not a null")
Erick Tryzelaar49d00b22012-09-24 16:55:42786 }
787 }
788
789 fn read_u64(&self) -> u64 { self.read_float() as u64 }
790 fn read_u32(&self) -> u32 { self.read_float() as u32 }
791 fn read_u16(&self) -> u16 { self.read_float() as u16 }
792 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
793 fn read_uint(&self) -> uint { self.read_float() as uint }
794
795 fn read_i64(&self) -> i64 { self.read_float() as i64 }
796 fn read_i32(&self) -> i32 { self.read_float() as i32 }
797 fn read_i16(&self) -> i16 { self.read_float() as i16 }
798 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
799 fn read_int(&self) -> int { self.read_float() as int }
800
801 fn read_bool(&self) -> bool {
802 debug!("read_bool");
803 match *self.pop() {
804 Boolean(b) => b,
Nick Desaulniers4445b382013-02-12 03:26:38805 _ => fail!(~"not a boolean")
Erick Tryzelaar49d00b22012-09-24 16:55:42806 }
807 }
808
809 fn read_f64(&self) -> f64 { self.read_float() as f64 }
810 fn read_f32(&self) -> f32 { self.read_float() as f32 }
811 fn read_float(&self) -> float {
812 debug!("read_float");
813 match *self.pop() {
814 Number(f) => f,
Nick Desaulniers4445b382013-02-12 03:26:38815 _ => fail!(~"not a number")
Erick Tryzelaar49d00b22012-09-24 16:55:42816 }
817 }
818
Erick Tryzelaar81423a32012-09-27 04:35:13819 fn read_char(&self) -> char {
Marvin Löbelb9de2b52013-03-24 06:51:18820 let mut v = ~[];
821 for str::each_char(self.read_owned_str()) |c| { v.push(c) }
Nick Desaulniers4445b382013-02-12 03:26:38822 if v.len() != 1 { fail!(~"string must have one character") }
Erick Tryzelaar81423a32012-09-27 04:35:13823 v[0]
824 }
825
826 fn read_owned_str(&self) -> ~str {
827 debug!("read_owned_str");
Erick Tryzelaar49d00b22012-09-24 16:55:42828 match *self.pop() {
829 String(ref s) => copy *s,
Nick Desaulniers4445b382013-02-12 03:26:38830 _ => fail!(~"not a string")
Erick Tryzelaar49d00b22012-09-24 16:55:42831 }
832 }
833
Erick Tryzelaar81423a32012-09-27 04:35:13834 fn read_managed_str(&self) -> @str {
Huon Wilson76dc7812012-12-10 02:29:33835 debug!("read_managed_str");
836 match *self.pop() {
837 String(ref s) => s.to_managed(),
Nick Desaulniers4445b382013-02-12 03:26:38838 _ => fail!(~"not a string")
Huon Wilson76dc7812012-12-10 02:29:33839 }
Erick Tryzelaar81423a32012-09-27 04:35:13840 }
841
Patrick Waltond18f7852013-03-07 22:38:38842 fn read_owned<T>(&self, f: &fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13843 debug!("read_owned()");
844 f()
845 }
846
Patrick Waltond18f7852013-03-07 22:38:38847 fn read_managed<T>(&self, f: &fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13848 debug!("read_managed()");
849 f()
850 }
851
Patrick Waltond18f7852013-03-07 22:38:38852 fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42853 debug!("read_enum(%s)", name);
Erick Tryzelaar49d00b22012-09-24 16:55:42854 f()
855 }
856
Erick Tryzelaar4d6dcef2013-03-27 01:46:48857 #[cfg(stage0)]
Patrick Waltond18f7852013-03-07 22:38:38858 fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42859 debug!("read_enum_variant()");
860 let idx = match *self.peek() {
861 Null => 0,
862 _ => 1,
863 };
864 f(idx)
865 }
866
Erick Tryzelaar4d6dcef2013-03-27 01:46:48867 #[cfg(stage1)]
868 #[cfg(stage2)]
869 #[cfg(stage3)]
870 fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
871 debug!("read_enum_variant(names=%?)", names);
872 let name = match *self.peek() {
873 String(ref s) => s,
874 List([String(ref s), .. _]) => s,
875 json => fail!(fmt!("invalid variant: %?", json)),
876 };
877 let idx = match vec::position(names, |n| str::eq_slice(*n, *name)) {
878 Some(idx) => idx,
879 None => fail!(fmt!("Unknown variant name: %?", name)),
880 };
881 f(idx)
882 }
883
Patrick Waltond18f7852013-03-07 22:38:38884 fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42885 debug!("read_enum_variant_arg(idx=%u)", idx);
Erick Tryzelaar4d6dcef2013-03-27 01:46:48886 match *self.peek() {
887 List(ref list) => {
888 self.stack.push(&list[idx + 1]);
889 f()
890 }
891 ref json => fail!(fmt!("not a list: %?", json)),
892 }
Erick Tryzelaar49d00b22012-09-24 16:55:42893 }
894
Patrick Waltond18f7852013-03-07 22:38:38895 fn read_owned_vec<T>(&self, f: &fn(uint) -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13896 debug!("read_owned_vec()");
897 let len = match *self.peek() {
Niko Matsakisa380df82013-02-08 03:33:12898 List(ref list) => list.len(),
Nick Desaulniers4445b382013-02-12 03:26:38899 _ => fail!(~"not a list"),
Erick Tryzelaar81423a32012-09-27 04:35:13900 };
901 let res = f(len);
902 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30903 res
Erick Tryzelaar81423a32012-09-27 04:35:13904 }
905
Patrick Waltond18f7852013-03-07 22:38:38906 fn read_managed_vec<T>(&self, f: &fn(uint) -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13907 debug!("read_owned_vec()");
Erick Tryzelaar49d00b22012-09-24 16:55:42908 let len = match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34909 List(ref list) => list.len(),
Nick Desaulniers4445b382013-02-12 03:26:38910 _ => fail!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42911 };
912 let res = f(len);
913 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30914 res
Erick Tryzelaar49d00b22012-09-24 16:55:42915 }
916
Patrick Waltond18f7852013-03-07 22:38:38917 fn read_vec_elt<T>(&self, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42918 debug!("read_vec_elt(idx=%u)", idx);
919 match *self.peek() {
920 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34921 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42922 f()
923 }
Nick Desaulniers4445b382013-02-12 03:26:38924 _ => fail!(~"not a list"),
Erick Tryzelaar49d00b22012-09-24 16:55:42925 }
926 }
927
Patrick Waltond18f7852013-03-07 22:38:38928 fn read_rec<T>(&self, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42929 debug!("read_rec()");
930 let value = f();
931 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30932 value
Erick Tryzelaar49d00b22012-09-24 16:55:42933 }
934
Patrick Waltond18f7852013-03-07 22:38:38935 fn read_struct<T>(&self, _name: &str, _len: uint, f: &fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13936 debug!("read_struct()");
937 let value = f();
938 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30939 value
Erick Tryzelaar81423a32012-09-27 04:35:13940 }
941
Patrick Waltond18f7852013-03-07 22:38:38942 fn read_field<T>(&self, name: &str, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13943 debug!("read_rec_field(%s, idx=%u)", name, idx);
Erick Tryzelaar49d00b22012-09-24 16:55:42944 let top = self.peek();
945 match *top {
946 Object(ref obj) => {
Daniel Micayee0a8c62013-01-23 16:47:43947 match obj.find(&name.to_owned()) {
Nick Desaulniers4445b382013-02-12 03:26:38948 None => fail!(fmt!("no such field: %s", name)),
Erick Tryzelaar49d00b22012-09-24 16:55:42949 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34950 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42951 f()
952 }
953 }
954 }
Nick Desaulniers4445b382013-02-12 03:26:38955 Number(_) => fail!(~"num"),
956 String(_) => fail!(~"str"),
957 Boolean(_) => fail!(~"bool"),
958 List(_) => fail!(fmt!("list: %?", top)),
959 Null => fail!(~"null"),
Erick Tryzelaar49d00b22012-09-24 16:55:42960
Nick Desaulniers4445b382013-02-12 03:26:38961 //_ => fail!(fmt!("not an object: %?", *top))
Erick Tryzelaar49d00b22012-09-24 16:55:42962 }
963 }
964
Patrick Waltond18f7852013-03-07 22:38:38965 fn read_tup<T>(&self, len: uint, f: &fn() -> T) -> T {
Erick Tryzelaar81423a32012-09-27 04:35:13966 debug!("read_tup(len=%u)", len);
Erick Tryzelaar49d00b22012-09-24 16:55:42967 let value = f();
968 self.pop();
Luqman Aden4cf51c22013-02-15 07:30:30969 value
Erick Tryzelaar49d00b22012-09-24 16:55:42970 }
971
Patrick Waltond18f7852013-03-07 22:38:38972 fn read_tup_elt<T>(&self, idx: uint, f: &fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42973 debug!("read_tup_elt(idx=%u)", idx);
974 match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34975 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34976 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42977 f()
978 }
Nick Desaulniers4445b382013-02-12 03:26:38979 _ => fail!(~"not a list")
Erick Tryzelaar49d00b22012-09-24 16:55:42980 }
981 }
Erick Tryzelaar478e4492013-03-26 22:26:05982
983 fn read_option<T>(&self, f: &fn() -> T) -> Option<T> {
984 match *self.peek() {
985 Null => { self.pop(); None }
986 _ => Some(f()),
987 }
988 }
Erick Tryzelaar49d00b22012-09-24 16:55:42989}
990
Patrick Walton91436882013-02-14 19:47:00991impl Eq for Json {
Patrick Waltonc1084092013-03-22 04:34:30992 fn eq(&self, other: &Json) -> bool {
Tim Chevalier3e7da962013-01-11 04:09:16993 match (self) {
994 &Number(f0) =>
995 match other { &Number(f1) => f0 == f1, _ => false },
996 &String(ref s0) =>
997 match other { &String(ref s1) => s0 == s1, _ => false },
998 &Boolean(b0) =>
999 match other { &Boolean(b1) => b0 == b1, _ => false },
1000 &Null =>
1001 match other { &Null => true, _ => false },
1002 &List(ref v0) =>
1003 match other { &List(ref v1) => v0 == v1, _ => false },
1004 &Object(ref d0) => {
1005 match other {
1006 &Object(ref d1) => {
Patrick Walton318e5342012-11-15 02:59:301007 if d0.len() == d1.len() {
1008 let mut equal = true;
Daniel Micay9599cc82013-02-08 02:03:131009 for d0.each |&(k, v0)| {
Daniel Micayee0a8c62013-01-23 16:47:431010 match d1.find(k) {
Patrick Walton318e5342012-11-15 02:59:301011 Some(v1) if v0 == v1 => { },
1012 _ => { equal = false; break }
1013 }
1014 };
1015 equal
1016 } else {
1017 false
1018 }
1019 }
1020 _ => false
1021 }
1022 }
1023 }
1024 }
Patrick Waltonc1084092013-03-22 04:34:301025 fn ne(&self, other: &Json) -> bool { !self.eq(other) }
Erick Tryzelaar49d00b22012-09-24 16:55:421026}
1027
Patrick Walton22b87572012-09-08 01:53:141028/// Test if two json values are less than one another
Patrick Walton91436882013-02-14 19:47:001029impl Ord for Json {
Patrick Waltonc1084092013-03-22 04:34:301030 fn lt(&self, other: &Json) -> bool {
Patrick Walton318e5342012-11-15 02:59:301031 match (*self) {
1032 Number(f0) => {
1033 match *other {
1034 Number(f1) => f0 < f1,
1035 String(_) | Boolean(_) | List(_) | Object(_) |
1036 Null => true
1037 }
1038 }
1039
1040 String(ref s0) => {
1041 match *other {
1042 Number(_) => false,
1043 String(ref s1) => s0 < s1,
1044 Boolean(_) | List(_) | Object(_) | Null => true
1045 }
1046 }
1047
1048 Boolean(b0) => {
1049 match *other {
1050 Number(_) | String(_) => false,
1051 Boolean(b1) => b0 < b1,
1052 List(_) | Object(_) | Null => true
1053 }
1054 }
1055
Patrick Walton98fdcb02012-12-08 03:34:571056 List(ref l0) => {
Patrick Walton318e5342012-11-15 02:59:301057 match *other {
1058 Number(_) | String(_) | Boolean(_) => false,
Patrick Walton98fdcb02012-12-08 03:34:571059 List(ref l1) => (*l0) < (*l1),
Patrick Walton318e5342012-11-15 02:59:301060 Object(_) | Null => true
1061 }
1062 }
1063
1064 Object(ref d0) => {
1065 match *other {
1066 Number(_) | String(_) | Boolean(_) | List(_) => false,
1067 Object(ref d1) => {
1068 unsafe {
1069 let mut d0_flat = ~[];
1070 let mut d1_flat = ~[];
1071
Tim Chevalier3e7da962013-01-11 04:09:161072 // FIXME #4430: this is horribly inefficient...
Daniel Micay9599cc82013-02-08 02:03:131073 for d0.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301074 d0_flat.push((@copy *k, @copy *v));
1075 }
1076 d0_flat.qsort();
1077
Daniel Micay9599cc82013-02-08 02:03:131078 for d1.each |&(k, v)| {
Patrick Walton318e5342012-11-15 02:59:301079 d1_flat.push((@copy *k, @copy *v));
1080 }
1081 d1_flat.qsort();
1082
1083 d0_flat < d1_flat
1084 }
1085 }
1086 Null => true
1087 }
1088 }
1089
1090 Null => {
1091 match *other {
1092 Number(_) | String(_) | Boolean(_) | List(_) |
1093 Object(_) =>
1094 false,
1095 Null => true
1096 }
1097 }
1098 }
1099 }
Patrick Waltonc1084092013-03-22 04:34:301100 fn le(&self, other: &Json) -> bool { !(*other).lt(&(*self)) }
1101 fn ge(&self, other: &Json) -> bool { !(*self).lt(other) }
1102 fn gt(&self, other: &Json) -> bool { (*other).lt(&(*self)) }
Patrick Walton22b87572012-09-08 01:53:141103}
1104
Ben Striegel0fed29c2013-03-08 02:11:091105trait ToJson { fn to_json(&self) -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:321106
Patrick Walton91436882013-02-14 19:47:001107impl ToJson for Json {
Ben Striegel0fed29c2013-03-08 02:11:091108 fn to_json(&self) -> Json { copy *self }
Erick Tryzelaared5af702012-05-28 19:10:321109}
1110
Patrick Walton91436882013-02-14 19:47:001111impl ToJson for @Json {
Ben Striegel0fed29c2013-03-08 02:11:091112 fn to_json(&self) -> Json { (**self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:541113}
1114
Patrick Walton91436882013-02-14 19:47:001115impl ToJson for int {
Ben Striegel0fed29c2013-03-08 02:11:091116 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541117}
1118
Patrick Walton91436882013-02-14 19:47:001119impl ToJson for i8 {
Ben Striegel0fed29c2013-03-08 02:11:091120 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321121}
1122
Patrick Walton91436882013-02-14 19:47:001123impl ToJson for i16 {
Ben Striegel0fed29c2013-03-08 02:11:091124 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321125}
1126
Patrick Walton91436882013-02-14 19:47:001127impl ToJson for i32 {
Ben Striegel0fed29c2013-03-08 02:11:091128 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321129}
1130
Patrick Walton91436882013-02-14 19:47:001131impl ToJson for i64 {
Ben Striegel0fed29c2013-03-08 02:11:091132 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321133}
1134
Patrick Walton91436882013-02-14 19:47:001135impl ToJson for uint {
Ben Striegel0fed29c2013-03-08 02:11:091136 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541137}
1138
Patrick Walton91436882013-02-14 19:47:001139impl ToJson for u8 {
Ben Striegel0fed29c2013-03-08 02:11:091140 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321141}
1142
Patrick Walton91436882013-02-14 19:47:001143impl ToJson for u16 {
Ben Striegel0fed29c2013-03-08 02:11:091144 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321145}
1146
Patrick Walton91436882013-02-14 19:47:001147impl ToJson for u32 {
Ben Striegel0fed29c2013-03-08 02:11:091148 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321149}
1150
Patrick Walton91436882013-02-14 19:47:001151impl ToJson for u64 {
Ben Striegel0fed29c2013-03-08 02:11:091152 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321153}
1154
Patrick Walton91436882013-02-14 19:47:001155impl ToJson for float {
Ben Striegel0fed29c2013-03-08 02:11:091156 fn to_json(&self) -> Json { Number(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321157}
1158
Patrick Walton91436882013-02-14 19:47:001159impl ToJson for f32 {
Ben Striegel0fed29c2013-03-08 02:11:091160 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321161}
1162
Patrick Walton91436882013-02-14 19:47:001163impl ToJson for f64 {
Ben Striegel0fed29c2013-03-08 02:11:091164 fn to_json(&self) -> Json { Number(*self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321165}
1166
Patrick Walton91436882013-02-14 19:47:001167impl ToJson for () {
Ben Striegel0fed29c2013-03-08 02:11:091168 fn to_json(&self) -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321169}
1170
Patrick Walton91436882013-02-14 19:47:001171impl ToJson for bool {
Ben Striegel0fed29c2013-03-08 02:11:091172 fn to_json(&self) -> Json { Boolean(*self) }
Erick Tryzelaared5af702012-05-28 19:10:321173}
1174
Patrick Walton91436882013-02-14 19:47:001175impl ToJson for ~str {
Ben Striegel0fed29c2013-03-08 02:11:091176 fn to_json(&self) -> Json { String(copy *self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511177}
1178
Patrick Walton91436882013-02-14 19:47:001179impl ToJson for @~str {
Ben Striegel0fed29c2013-03-08 02:11:091180 fn to_json(&self) -> Json { String(copy **self) }
Erick Tryzelaared5af702012-05-28 19:10:321181}
1182
Patrick Waltonbf2a2252013-02-21 01:07:171183impl<A:ToJson,B:ToJson> ToJson for (A, B) {
Ben Striegel0fed29c2013-03-08 02:11:091184 fn to_json(&self) -> Json {
1185 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181186 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421187 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561188 }
1189 }
Erick Tryzelaared5af702012-05-28 19:10:321190 }
1191}
1192
Patrick Waltonbf2a2252013-02-21 01:07:171193impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
Ben Striegel0fed29c2013-03-08 02:11:091194 fn to_json(&self) -> Json {
1195 match *self {
Brian Andersonbc9efaa2012-09-28 07:22:181196 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421197 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561198 }
1199 }
Erick Tryzelaared5af702012-05-28 19:10:321200 }
1201}
1202
Patrick Waltonbf2a2252013-02-21 01:07:171203impl<A:ToJson> ToJson for ~[A] {
Ben Striegel0fed29c2013-03-08 02:11:091204 fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321205}
1206
Patrick Waltonbf2a2252013-02-21 01:07:171207impl<A:ToJson + Copy> ToJson for LinearMap<~str, A> {
Ben Striegel0fed29c2013-03-08 02:11:091208 fn to_json(&self) -> Json {
Daniel Micay7f0fa142013-01-23 22:06:321209 let mut d = LinearMap::new();
Daniel Micay9599cc82013-02-08 02:03:131210 for self.each |&(key, value)| {
Erick Tryzelaar49d00b22012-09-24 16:55:421211 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321212 }
Erick Tryzelaar49d00b22012-09-24 16:55:421213 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321214 }
1215}
1216
Patrick Waltonbf2a2252013-02-21 01:07:171217impl<A:ToJson> ToJson for Option<A> {
Ben Striegel0fed29c2013-03-08 02:11:091218 fn to_json(&self) -> Json {
1219 match *self {
Ben Striegela605fd02012-08-11 14:08:421220 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181221 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321222 }
1223 }
1224}
1225
Patrick Walton91436882013-02-14 19:47:001226impl to_str::ToStr for Json {
Patrick Waltonc1084092013-03-22 04:34:301227 fn to_str(&self) -> ~str { to_str(self) }
Erick Tryzelaared5af702012-05-28 19:10:321228}
1229
Patrick Walton91436882013-02-14 19:47:001230impl to_str::ToStr for Error {
Patrick Waltonc1084092013-03-22 04:34:301231 fn to_str(&self) -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521232 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381233 }
1234}
1235
Brian Anderson6e27b272012-01-18 03:05:071236#[cfg(test)]
1237mod tests {
Erick Tryzelaarb2908632013-03-27 00:46:291238 use super::*;
1239
Patrick Walton2db3abd2013-01-09 03:37:251240 use core::prelude::*;
Daniel Micay7f0fa142013-01-23 22:06:321241 use core::hashmap::linear::LinearMap;
John Clementsf91160b2013-02-08 01:06:261242
Erick Tryzelaarb10b8c32013-03-27 07:13:011243 use std::serialize::Decodable;
1244
Erick Tryzelaar49d00b22012-09-24 16:55:421245 fn mk_object(items: &[(~str, Json)]) -> Json {
Daniel Micaybba55202013-01-24 02:09:501246 let mut d = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:321247
Erick Tryzelaar49d00b22012-09-24 16:55:421248 for items.each |item| {
1249 match *item {
Luqman Aden4cf51c22013-02-15 07:30:301250 (copy key, copy value) => { d.insert(key, value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421251 }
Erick Tryzelaar012dec52012-02-26 00:39:321252 };
1253
Luqman Aden4cf51c22013-02-15 07:30:301254 Object(d)
Brian Anderson6e27b272012-01-18 03:05:071255 }
1256
1257 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321258 fn test_write_null() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001259 assert_eq!(to_str(&Null), ~"null");
Brian Anderson6e27b272012-01-18 03:05:071260 }
1261
1262 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421263 fn test_write_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001264 assert_eq!(to_str(&Number(3f)), ~"3");
1265 assert_eq!(to_str(&Number(3.1f)), ~"3.1");
1266 assert_eq!(to_str(&Number(-1.5f)), ~"-1.5");
1267 assert_eq!(to_str(&Number(0.5f)), ~"0.5");
Brian Anderson6e27b272012-01-18 03:05:071268 }
1269
1270 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321271 fn test_write_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001272 assert_eq!(to_str(&String(~"")), ~"\"\"");
1273 assert_eq!(to_str(&String(~"foo")), ~"\"foo\"");
Brian Anderson6e27b272012-01-18 03:05:071274 }
1275
1276 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321277 fn test_write_bool() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001278 assert_eq!(to_str(&Boolean(true)), ~"true");
1279 assert_eq!(to_str(&Boolean(false)), ~"false");
Brian Anderson6e27b272012-01-18 03:05:071280 }
1281
1282 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321283 fn test_write_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001284 assert_eq!(to_str(&List(~[])), ~"[]");
1285 assert_eq!(to_str(&List(~[Boolean(true)])), ~"[true]");
1286 assert_eq!(to_str(&List(~[
Ben Striegela605fd02012-08-11 14:08:421287 Boolean(false),
1288 Null,
Erick Tryzelaar49d00b22012-09-24 16:55:421289 List(~[String(~"foo\nbar"), Number(3.5f)])
Erick Tryzelaar6cf99fa2013-03-27 00:23:001290 ])), ~"[false,null,[\"foo\\nbar\",3.5]]");
Erick Tryzelaar012dec52012-02-26 00:39:321291 }
1292
1293 #[test]
Erick Tryzelaarc9188c82013-03-27 00:34:491294 fn test_write_list_pretty() {
1295 assert_eq!(to_pretty_str(&List(~[])), ~"[]");
1296 assert_eq!(
1297 to_pretty_str(&List(~[Boolean(true)])),
1298 ~"\
1299 [\n \
1300 true\n\
1301 ]"
1302 );
1303 assert_eq!(
1304 to_pretty_str(&List(~[
1305 Boolean(false),
1306 Null,
1307 List(~[String(~"foo\nbar"), Number(3.5f)])
1308 ])),
1309 ~"\
1310 [\n \
1311 false,\n \
1312 null,\n \
1313 [\n \
1314 \"foo\\nbar\",\n \
1315 3.5\n \
1316 ]\n\
1317 ]"
1318 );
1319 }
1320
1321 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421322 fn test_write_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001323 assert_eq!(to_str(&mk_object(~[])), ~"{}");
1324 assert_eq!(
1325 to_str(&mk_object(~[(~"a", Boolean(true))])),
1326 ~"{\"a\":true}"
1327 );
Erick Tryzelaarc9188c82013-03-27 00:34:491328 assert_eq!(
1329 to_str(&mk_object(~[
1330 (~"b", List(~[
1331 mk_object(~[(~"c", String(~"\x0c\r"))]),
1332 mk_object(~[(~"d", String(~""))])
1333 ]))
1334 ])),
1335 ~"{\
1336 \"b\":[\
1337 {\"c\":\"\\f\\r\"},\
1338 {\"d\":\"\"}\
1339 ]\
1340 }"
1341 );
Erick Tryzelaar49d00b22012-09-24 16:55:421342 let a = mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421343 (~"a", Boolean(true)),
Erick Tryzelaar49d00b22012-09-24 16:55:421344 (~"b", List(~[
1345 mk_object(~[(~"c", String(~"\x0c\r"))]),
1346 mk_object(~[(~"d", String(~""))])
Michael Sullivan98e161f2012-06-29 23:26:561347 ]))
Graydon Hoare11871b82012-08-30 23:27:151348 ]);
Erick Tryzelaar49d00b22012-09-24 16:55:421349 // We can't compare the strings directly because the object fields be
1350 // printed in a different order.
Erick Tryzelaar6cf99fa2013-03-27 00:23:001351 let b = from_str(to_str(&a)).unwrap();
1352 assert_eq!(a, b);
Erick Tryzelaar012dec52012-02-26 00:39:321353 }
1354
John Clementsf91160b2013-02-08 01:06:261355 #[test]
Erick Tryzelaarc9188c82013-03-27 00:34:491356 fn test_write_object_pretty() {
1357 assert_eq!(to_pretty_str(&mk_object(~[])), ~"{\n}");
1358 assert_eq!(
1359 to_pretty_str(&mk_object(~[(~"a", Boolean(true))])),
1360 ~"\
1361 {\n \
1362 \"a\": true\n\
1363 }"
1364 );
1365 assert_eq!(
1366 to_pretty_str(&mk_object(~[
1367 (~"b", List(~[
1368 mk_object(~[(~"c", String(~"\x0c\r"))]),
1369 mk_object(~[(~"d", String(~""))])
1370 ]))
1371 ])),
1372 ~"\
1373 {\n \
1374 \"b\": [\n \
1375 {\n \
1376 \"c\": \"\\f\\r\"\n \
1377 },\n \
1378 {\n \
1379 \"d\": \"\"\n \
1380 }\n \
1381 ]\n\
1382 }"
1383 );
1384 let a = mk_object(~[
1385 (~"a", Boolean(true)),
1386 (~"b", List(~[
1387 mk_object(~[(~"c", String(~"\x0c\r"))]),
1388 mk_object(~[(~"d", String(~""))])
1389 ]))
1390 ]);
1391 // We can't compare the strings directly because the object fields be
1392 // printed in a different order.
1393 let b = from_str(to_str(&a)).unwrap();
1394 assert_eq!(a, b);
1395 }
1396
1397 #[auto_encode]
Erick Tryzelaarb10b8c32013-03-27 07:13:011398 #[auto_decode]
1399 #[deriving(Eq)]
Erick Tryzelaarc9188c82013-03-27 00:34:491400 enum Animal {
1401 Dog,
1402 Frog(~str, int)
1403 }
1404
1405 #[test]
1406 fn test_write_enum_no_args() {
1407 let animal = Dog;
1408
Erick Tryzelaar6cf99fa2013-03-27 00:23:001409 let s = do io::with_str_writer |wr| {
Erick Tryzelaarc9188c82013-03-27 00:34:491410 let encoder = Encoder(wr);
1411 animal.encode(&encoder);
Erick Tryzelaar6cf99fa2013-03-27 00:23:001412 };
Erick Tryzelaar4d995e62013-03-27 07:14:521413 assert_eq!(s, ~"\"Dog\"");
Erick Tryzelaarc9188c82013-03-27 00:34:491414 }
1415
1416 #[test]
1417 fn test_write_enum_no_args_pretty() {
1418 let animal = Dog;
1419
1420 let s = do io::with_str_writer |wr| {
1421 let encoder = PrettyEncoder(wr);
1422 animal.encode(&encoder);
1423 };
Erick Tryzelaar4d995e62013-03-27 07:14:521424 assert_eq!(s, ~"\"Dog\"");
Erick Tryzelaarc9188c82013-03-27 00:34:491425 }
1426
1427 #[test]
1428 fn test_write_enum_multiple_args() {
1429 let animal = Frog(~"Henry", 349);
1430
1431 let s = do io::with_str_writer |wr| {
1432 let encoder = Encoder(wr);
1433 animal.encode(&encoder);
1434 };
Erick Tryzelaar4d995e62013-03-27 07:14:521435 assert_eq!(s, ~"[\"Frog\",\"Henry\",349]");
Erick Tryzelaarc9188c82013-03-27 00:34:491436 }
1437
1438 #[test]
1439 fn test_write_enum_multiple_args_pretty() {
1440 let animal = Frog(~"Henry", 349);
1441
1442 let s = do io::with_str_writer |wr| {
1443 let encoder = PrettyEncoder(wr);
1444 animal.encode(&encoder);
1445 };
1446 assert_eq!(
1447 s,
1448 ~"\
1449 [\n \
1450 \"Frog\",\n \
Erick Tryzelaar4d995e62013-03-27 07:14:521451 \"Henry\",\n \
1452 349\n\
Erick Tryzelaarc9188c82013-03-27 00:34:491453 ]"
1454 );
John Clementsc952c042013-02-08 23:36:401455 }
1456
1457 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001458 fn test_write_some() {
1459 let value = Some(~"jodhpurs");
1460 let s = do io::with_str_writer |wr| {
1461 let encoder = Encoder(wr);
1462 value.encode(&encoder);
1463 };
1464 assert_eq!(s, ~"\"jodhpurs\"");
John Clementsc952c042013-02-08 23:36:401465 }
1466
1467 #[test]
Erick Tryzelaarc9188c82013-03-27 00:34:491468 fn test_write_some_pretty() {
1469 let value = Some(~"jodhpurs");
1470 let s = do io::with_str_writer |wr| {
1471 let encoder = PrettyEncoder(wr);
1472 value.encode(&encoder);
1473 };
1474 assert_eq!(s, ~"\"jodhpurs\"");
1475 }
1476
1477 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001478 fn test_write_none() {
1479 let value: Option<~str> = None;
1480 let s = do io::with_str_writer |wr| {
1481 let encoder = Encoder(wr);
1482 value.encode(&encoder);
1483 };
1484 assert_eq!(s, ~"null");
John Clementsf91160b2013-02-08 01:06:261485 }
1486
Erick Tryzelaar012dec52012-02-26 00:39:321487 #[test]
Erick Tryzelaarc9188c82013-03-27 00:34:491488 fn test_write_none_pretty() {
1489 let value: Option<~str> = None;
1490 let s = do io::with_str_writer |wr| {
1491 let encoder = Encoder(wr);
1492 value.encode(&encoder);
1493 };
1494 assert_eq!(s, ~"null");
1495 }
1496
1497 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321498 fn test_trailing_characters() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001499 assert_eq!(from_str(~"nulla"),
Patrick Waltond7e74b52013-03-06 21:58:021500 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001501 assert_eq!(from_str(~"truea"),
Patrick Waltond7e74b52013-03-06 21:58:021502 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001503 assert_eq!(from_str(~"falsea"),
Patrick Waltond7e74b52013-03-06 21:58:021504 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001505 assert_eq!(from_str(~"1a"),
Patrick Waltond7e74b52013-03-06 21:58:021506 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001507 assert_eq!(from_str(~"[]a"),
Patrick Waltond7e74b52013-03-06 21:58:021508 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001509 assert_eq!(from_str(~"{}a"),
Patrick Waltond7e74b52013-03-06 21:58:021510 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar012dec52012-02-26 00:39:321511 }
1512
1513 #[test]
1514 fn test_read_identifiers() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001515 assert_eq!(from_str(~"n"),
Patrick Waltond7e74b52013-03-06 21:58:021516 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001517 assert_eq!(from_str(~"nul"),
Patrick Waltond7e74b52013-03-06 21:58:021518 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321519
Erick Tryzelaar6cf99fa2013-03-27 00:23:001520 assert_eq!(from_str(~"t"),
Patrick Waltond7e74b52013-03-06 21:58:021521 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001522 assert_eq!(from_str(~"truz"),
Patrick Waltond7e74b52013-03-06 21:58:021523 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321524
Erick Tryzelaar6cf99fa2013-03-27 00:23:001525 assert_eq!(from_str(~"f"),
Patrick Waltond7e74b52013-03-06 21:58:021526 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001527 assert_eq!(from_str(~"faz"),
Patrick Waltond7e74b52013-03-06 21:58:021528 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321529
Erick Tryzelaar6cf99fa2013-03-27 00:23:001530 assert_eq!(from_str(~"null"), Ok(Null));
1531 assert_eq!(from_str(~"true"), Ok(Boolean(true)));
1532 assert_eq!(from_str(~"false"), Ok(Boolean(false)));
1533 assert_eq!(from_str(~" null "), Ok(Null));
1534 assert_eq!(from_str(~" true "), Ok(Boolean(true)));
1535 assert_eq!(from_str(~" false "), Ok(Boolean(false)));
Erick Tryzelaar012dec52012-02-26 00:39:321536 }
1537
1538 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421539 fn test_read_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001540 assert_eq!(from_str(~"+"),
Patrick Waltond7e74b52013-03-06 21:58:021541 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001542 assert_eq!(from_str(~"."),
Patrick Waltond7e74b52013-03-06 21:58:021543 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321544
Erick Tryzelaar6cf99fa2013-03-27 00:23:001545 assert_eq!(from_str(~"-"),
Patrick Waltond7e74b52013-03-06 21:58:021546 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001547 assert_eq!(from_str(~"00"),
Patrick Waltond7e74b52013-03-06 21:58:021548 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001549 assert_eq!(from_str(~"1."),
Patrick Waltond7e74b52013-03-06 21:58:021550 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001551 assert_eq!(from_str(~"1e"),
Patrick Waltond7e74b52013-03-06 21:58:021552 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001553 assert_eq!(from_str(~"1e+"),
Patrick Waltond7e74b52013-03-06 21:58:021554 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"}));
Erick Tryzelaar012dec52012-02-26 00:39:321555
Erick Tryzelaar6cf99fa2013-03-27 00:23:001556 assert_eq!(from_str(~"3"), Ok(Number(3f)));
1557 assert_eq!(from_str(~"3.1"), Ok(Number(3.1f)));
1558 assert_eq!(from_str(~"-1.2"), Ok(Number(-1.2f)));
1559 assert_eq!(from_str(~"0.4"), Ok(Number(0.4f)));
1560 assert_eq!(from_str(~"0.4e5"), Ok(Number(0.4e5f)));
1561 assert_eq!(from_str(~"0.4e+15"), Ok(Number(0.4e15f)));
1562 assert_eq!(from_str(~"0.4e-01"), Ok(Number(0.4e-01f)));
1563 assert_eq!(from_str(~" 3 "), Ok(Number(3f)));
Erick Tryzelaar012dec52012-02-26 00:39:321564 }
1565
1566 #[test]
1567 fn test_read_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001568 assert_eq!(from_str(~"\""),
Patrick Waltond7e74b52013-03-06 21:58:021569 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"
1570 }));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001571 assert_eq!(from_str(~"\"lol"),
Patrick Waltond7e74b52013-03-06 21:58:021572 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"
1573 }));
Erick Tryzelaar012dec52012-02-26 00:39:321574
Erick Tryzelaar6cf99fa2013-03-27 00:23:001575 assert_eq!(from_str(~"\"\""), Ok(String(~"")));
1576 assert_eq!(from_str(~"\"foo\""), Ok(String(~"foo")));
1577 assert_eq!(from_str(~"\"\\\"\""), Ok(String(~"\"")));
1578 assert_eq!(from_str(~"\"\\b\""), Ok(String(~"\x08")));
1579 assert_eq!(from_str(~"\"\\n\""), Ok(String(~"\n")));
1580 assert_eq!(from_str(~"\"\\r\""), Ok(String(~"\r")));
1581 assert_eq!(from_str(~"\"\\t\""), Ok(String(~"\t")));
1582 assert_eq!(from_str(~" \"foo\" "), Ok(String(~"foo")));
Erick Tryzelaar012dec52012-02-26 00:39:321583 }
1584
1585 #[test]
Kevin Cantucf386182012-08-31 04:03:191586 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001587 assert_eq!(from_str(~"\"\\u12ab\""), Ok(String(~"\u12ab")));
1588 assert_eq!(from_str(~"\"\\uAB12\""), Ok(String(~"\uAB12")));
Kevin Cantucf386182012-08-31 04:03:191589 }
1590
1591 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321592 fn test_read_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001593 assert_eq!(from_str(~"["),
Patrick Waltond7e74b52013-03-06 21:58:021594 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001595 assert_eq!(from_str(~"[1"),
Patrick Waltond7e74b52013-03-06 21:58:021596 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001597 assert_eq!(from_str(~"[1,"),
Patrick Waltond7e74b52013-03-06 21:58:021598 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001599 assert_eq!(from_str(~"[1,]"),
Patrick Waltond7e74b52013-03-06 21:58:021600 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001601 assert_eq!(from_str(~"[6 7]"),
Patrick Waltond7e74b52013-03-06 21:58:021602 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"}));
Erick Tryzelaar012dec52012-02-26 00:39:321603
Erick Tryzelaar6cf99fa2013-03-27 00:23:001604 assert_eq!(from_str(~"[]"), Ok(List(~[])));
1605 assert_eq!(from_str(~"[ ]"), Ok(List(~[])));
1606 assert_eq!(from_str(~"[true]"), Ok(List(~[Boolean(true)])));
1607 assert_eq!(from_str(~"[ false ]"), Ok(List(~[Boolean(false)])));
1608 assert_eq!(from_str(~"[null]"), Ok(List(~[Null])));
1609 assert_eq!(from_str(~"[3, 1]"),
Patrick Waltond7e74b52013-03-06 21:58:021610 Ok(List(~[Number(3f), Number(1f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001611 assert_eq!(from_str(~"\n[3, 2]\n"),
Patrick Waltond7e74b52013-03-06 21:58:021612 Ok(List(~[Number(3f), Number(2f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001613 assert_eq!(from_str(~"[2, [4, 1]]"),
Patrick Waltond7e74b52013-03-06 21:58:021614 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])])));
Erick Tryzelaar012dec52012-02-26 00:39:321615 }
1616
1617 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421618 fn test_read_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001619 assert_eq!(from_str(~"{"),
Patrick Waltond7e74b52013-03-06 21:58:021620 Err(Error {
1621 line: 1u,
1622 col: 2u,
1623 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001624 assert_eq!(from_str(~"{ "),
Patrick Waltond7e74b52013-03-06 21:58:021625 Err(Error {
1626 line: 1u,
1627 col: 3u,
1628 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001629 assert_eq!(from_str(~"{1"),
Patrick Waltond7e74b52013-03-06 21:58:021630 Err(Error {
1631 line: 1u,
1632 col: 2u,
1633 msg: @~"key must be a string"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001634 assert_eq!(from_str(~"{ \"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021635 Err(Error {
1636 line: 1u,
1637 col: 6u,
1638 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001639 assert_eq!(from_str(~"{\"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021640 Err(Error {
1641 line: 1u,
1642 col: 5u,
1643 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001644 assert_eq!(from_str(~"{\"a\" "),
Patrick Waltond7e74b52013-03-06 21:58:021645 Err(Error {
1646 line: 1u,
1647 col: 6u,
1648 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321649
Erick Tryzelaar6cf99fa2013-03-27 00:23:001650 assert_eq!(from_str(~"{\"a\" 1"),
Patrick Waltond7e74b52013-03-06 21:58:021651 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001652 assert_eq!(from_str(~"{\"a\":"),
Patrick Waltond7e74b52013-03-06 21:58:021653 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001654 assert_eq!(from_str(~"{\"a\":1"),
Patrick Waltond7e74b52013-03-06 21:58:021655 Err(Error {
1656 line: 1u,
1657 col: 7u,
1658 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001659 assert_eq!(from_str(~"{\"a\":1 1"),
Patrick Waltond7e74b52013-03-06 21:58:021660 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001661 assert_eq!(from_str(~"{\"a\":1,"),
Patrick Waltond7e74b52013-03-06 21:58:021662 Err(Error {
1663 line: 1u,
1664 col: 8u,
1665 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321666
Erick Tryzelaar6cf99fa2013-03-27 00:23:001667 assert_eq!(result::unwrap(from_str(~"{}")), mk_object(~[]));
1668 assert_eq!(result::unwrap(from_str(~"{\"a\": 3}")),
Patrick Waltond7e74b52013-03-06 21:58:021669 mk_object(~[(~"a", Number(3.0f))]));
Erick Tryzelaar012dec52012-02-26 00:39:321670
Erick Tryzelaar6cf99fa2013-03-27 00:23:001671 assert_eq!(result::unwrap(from_str(
1672 ~"{ \"a\": null, \"b\" : true }")),
Erick Tryzelaar49d00b22012-09-24 16:55:421673 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421674 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021675 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001676 assert_eq!(result::unwrap(
1677 from_str(~"\n{ \"a\": null, \"b\" : true }\n")),
Erick Tryzelaar49d00b22012-09-24 16:55:421678 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421679 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021680 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001681 assert_eq!(result::unwrap(from_str(
1682 ~"{\"a\" : 1.0 ,\"b\": [ true ]}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421683 mk_object(~[
1684 (~"a", Number(1.0)),
1685 (~"b", List(~[Boolean(true)]))
Patrick Waltond7e74b52013-03-06 21:58:021686 ]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001687 assert_eq!(result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481688 ~"{" +
1689 ~"\"a\": 1.0, " +
1690 ~"\"b\": [" +
1691 ~"true," +
1692 ~"\"foo\\nbar\", " +
1693 ~"{ \"c\": {\"d\": null} } " +
1694 ~"]" +
Erick Tryzelaar6cf99fa2013-03-27 00:23:001695 ~"}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421696 mk_object(~[
1697 (~"a", Number(1.0f)),
1698 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421699 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421700 String(~"foo\nbar"),
1701 mk_object(~[
1702 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561703 ])
1704 ]))
Patrick Waltond7e74b52013-03-06 21:58:021705 ]));
Erick Tryzelaar012dec52012-02-26 00:39:321706 }
1707
1708 #[test]
Erick Tryzelaarb10b8c32013-03-27 07:13:011709 fn test_read_none() {
1710 let decoder = Decoder(from_str(~"null").unwrap());
1711 let value: Option<~str> = Decodable::decode(&decoder);
1712 assert_eq!(value, None);
1713 }
1714
1715 #[test]
1716 fn test_read_some() {
1717 let decoder = Decoder(from_str(~"\"jodhpurs\"").unwrap());
1718 let value: Option<~str> = Decodable::decode(&decoder);
1719 assert_eq!(value, Some(~"jodhpurs"));
1720 }
1721
1722 #[test]
Erick Tryzelaar4e9a63f2013-03-27 00:42:011723 fn test_read_enum_no_args() {
1724 let decoder = Decoder(from_str(~"\"Dog\"").unwrap());
1725 let value: Animal = Decodable::decode(&decoder);
1726 assert_eq!(value, Dog);
1727 }
1728
1729 #[test]
1730 fn test_read_enum_multiple_args() {
1731 let decoder = Decoder(from_str(~"[\"Frog\",\"Henry\",349]").unwrap());
1732 let value: Animal = Decodable::decode(&decoder);
1733 assert_eq!(value, Frog(~"Henry", 349));
1734 }
1735
1736 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321737 fn test_multiline_errors() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001738 assert_eq!(from_str(~"{\n \"foo\":\n \"bar\""),
Patrick Waltond7e74b52013-03-06 21:58:021739 Err(Error {
1740 line: 3u,
1741 col: 8u,
1742 msg: @~"EOF while parsing object"}));
Brian Anderson6e27b272012-01-18 03:05:071743 }
1744}