blob: d6606981b1b6adf5fc517be29f81d8f027218566 [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 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 Micay7f0fa142013-01-23 22:06:32680 let mut values = ~LinearMap::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
Patrick Waltonbf2a2252013-02-21 01:07:171130impl<A:ToJson + Copy> ToJson for LinearMap<~str, A> {
Ben Striegel0fed29c2013-03-08 02:11:091131 fn to_json(&self) -> Json {
Daniel Micay7f0fa142013-01-23 22:06:321132 let mut d = LinearMap::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 Micay7f0fa142013-01-23 22:06:321164 use core::hashmap::linear::LinearMap;
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 Tryzelaar49d00b22012-09-24 16:55:421176 fn mk_object(items: &[(~str, Json)]) -> Json {
Daniel Micaybba55202013-01-24 02:09:501177 let mut d = ~LinearMap::new();
Erick Tryzelaar012dec52012-02-26 00:39:321178
Erick Tryzelaar49d00b22012-09-24 16:55:421179 for items.each |item| {
1180 match *item {
Luqman Aden4cf51c22013-02-15 07:30:301181 (copy key, copy value) => { d.insert(key, value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421182 }
Erick Tryzelaar012dec52012-02-26 00:39:321183 };
1184
Luqman Aden4cf51c22013-02-15 07:30:301185 Object(d)
Brian Anderson6e27b272012-01-18 03:05:071186 }
1187
1188 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321189 fn test_write_null() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001190 assert_eq!(to_str(&Null), ~"null");
Erick Tryzelaar9bbf3842013-03-30 18:08:571191 assert_eq!(to_pretty_str(&Null), ~"null");
Brian Anderson6e27b272012-01-18 03:05:071192 }
1193
Erick Tryzelaar9bbf3842013-03-30 18:08:571194
Brian Anderson6e27b272012-01-18 03:05:071195 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421196 fn test_write_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001197 assert_eq!(to_str(&Number(3f)), ~"3");
Erick Tryzelaar9bbf3842013-03-30 18:08:571198 assert_eq!(to_pretty_str(&Number(3f)), ~"3");
1199
Erick Tryzelaar6cf99fa2013-03-27 00:23:001200 assert_eq!(to_str(&Number(3.1f)), ~"3.1");
Erick Tryzelaar9bbf3842013-03-30 18:08:571201 assert_eq!(to_pretty_str(&Number(3.1f)), ~"3.1");
1202
Erick Tryzelaar6cf99fa2013-03-27 00:23:001203 assert_eq!(to_str(&Number(-1.5f)), ~"-1.5");
Erick Tryzelaar9bbf3842013-03-30 18:08:571204 assert_eq!(to_pretty_str(&Number(-1.5f)), ~"-1.5");
1205
Erick Tryzelaar6cf99fa2013-03-27 00:23:001206 assert_eq!(to_str(&Number(0.5f)), ~"0.5");
Erick Tryzelaar9bbf3842013-03-30 18:08:571207 assert_eq!(to_pretty_str(&Number(0.5f)), ~"0.5");
Brian Anderson6e27b272012-01-18 03:05:071208 }
1209
1210 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321211 fn test_write_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001212 assert_eq!(to_str(&String(~"")), ~"\"\"");
Erick Tryzelaar9bbf3842013-03-30 18:08:571213 assert_eq!(to_pretty_str(&String(~"")), ~"\"\"");
1214
Erick Tryzelaar6cf99fa2013-03-27 00:23:001215 assert_eq!(to_str(&String(~"foo")), ~"\"foo\"");
Erick Tryzelaar9bbf3842013-03-30 18:08:571216 assert_eq!(to_pretty_str(&String(~"foo")), ~"\"foo\"");
Brian Anderson6e27b272012-01-18 03:05:071217 }
1218
1219 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321220 fn test_write_bool() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001221 assert_eq!(to_str(&Boolean(true)), ~"true");
Erick Tryzelaar9bbf3842013-03-30 18:08:571222 assert_eq!(to_pretty_str(&Boolean(true)), ~"true");
1223
Erick Tryzelaar6cf99fa2013-03-27 00:23:001224 assert_eq!(to_str(&Boolean(false)), ~"false");
Erick Tryzelaar9bbf3842013-03-30 18:08:571225 assert_eq!(to_pretty_str(&Boolean(false)), ~"false");
Brian Anderson6e27b272012-01-18 03:05:071226 }
1227
1228 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321229 fn test_write_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001230 assert_eq!(to_str(&List(~[])), ~"[]");
Erick Tryzelaarc9188c82013-03-27 00:34:491231 assert_eq!(to_pretty_str(&List(~[])), ~"[]");
Erick Tryzelaar9bbf3842013-03-30 18:08:571232
1233 assert_eq!(to_str(&List(~[Boolean(true)])), ~"[true]");
Erick Tryzelaarc9188c82013-03-27 00:34:491234 assert_eq!(
1235 to_pretty_str(&List(~[Boolean(true)])),
1236 ~"\
1237 [\n \
1238 true\n\
1239 ]"
1240 );
Erick Tryzelaar9bbf3842013-03-30 18:08:571241
1242 assert_eq!(to_str(&List(~[
1243 Boolean(false),
1244 Null,
1245 List(~[String(~"foo\nbar"), Number(3.5f)])
1246 ])), ~"[false,null,[\"foo\\nbar\",3.5]]");
Erick Tryzelaarc9188c82013-03-27 00:34:491247 assert_eq!(
1248 to_pretty_str(&List(~[
1249 Boolean(false),
1250 Null,
1251 List(~[String(~"foo\nbar"), Number(3.5f)])
1252 ])),
1253 ~"\
1254 [\n \
1255 false,\n \
1256 null,\n \
1257 [\n \
1258 \"foo\\nbar\",\n \
1259 3.5\n \
1260 ]\n\
1261 ]"
1262 );
1263 }
1264
1265 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421266 fn test_write_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001267 assert_eq!(to_str(&mk_object(~[])), ~"{}");
Erick Tryzelaar9bbf3842013-03-30 18:08:571268 assert_eq!(to_pretty_str(&mk_object(~[])), ~"{}");
1269
Erick Tryzelaar6cf99fa2013-03-27 00:23:001270 assert_eq!(
1271 to_str(&mk_object(~[(~"a", Boolean(true))])),
1272 ~"{\"a\":true}"
1273 );
Erick Tryzelaarc9188c82013-03-27 00:34:491274 assert_eq!(
Erick Tryzelaar9bbf3842013-03-30 18:08:571275 to_pretty_str(&mk_object(~[(~"a", Boolean(true))])),
1276 ~"\
1277 {\n \
1278 \"a\": true\n\
1279 }"
1280 );
1281
1282 assert_eq!(
Erick Tryzelaarc9188c82013-03-27 00:34:491283 to_str(&mk_object(~[
1284 (~"b", List(~[
1285 mk_object(~[(~"c", String(~"\x0c\r"))]),
1286 mk_object(~[(~"d", String(~""))])
1287 ]))
1288 ])),
1289 ~"{\
1290 \"b\":[\
1291 {\"c\":\"\\f\\r\"},\
1292 {\"d\":\"\"}\
1293 ]\
1294 }"
1295 );
Erick Tryzelaarc9188c82013-03-27 00:34:491296 assert_eq!(
1297 to_pretty_str(&mk_object(~[
1298 (~"b", List(~[
1299 mk_object(~[(~"c", String(~"\x0c\r"))]),
1300 mk_object(~[(~"d", String(~""))])
1301 ]))
1302 ])),
1303 ~"\
1304 {\n \
1305 \"b\": [\n \
1306 {\n \
1307 \"c\": \"\\f\\r\"\n \
1308 },\n \
1309 {\n \
1310 \"d\": \"\"\n \
1311 }\n \
1312 ]\n\
1313 }"
1314 );
Erick Tryzelaar9bbf3842013-03-30 18:08:571315
Erick Tryzelaarc9188c82013-03-27 00:34:491316 let a = mk_object(~[
1317 (~"a", Boolean(true)),
1318 (~"b", List(~[
1319 mk_object(~[(~"c", String(~"\x0c\r"))]),
1320 mk_object(~[(~"d", String(~""))])
1321 ]))
1322 ]);
Erick Tryzelaar9bbf3842013-03-30 18:08:571323
Erick Tryzelaarc9188c82013-03-27 00:34:491324 // We can't compare the strings directly because the object fields be
1325 // printed in a different order.
Erick Tryzelaar9bbf3842013-03-30 18:08:571326 assert_eq!(copy a, from_str(to_str(&a)).unwrap());
1327 assert_eq!(copy a, from_str(to_pretty_str(&a)).unwrap());
Erick Tryzelaarc9188c82013-03-27 00:34:491328 }
1329
1330 #[test]
Erick Tryzelaar9bbf3842013-03-30 18:08:571331 fn test_write_enum() {
Erick Tryzelaarc9188c82013-03-27 00:34:491332 let animal = Dog;
Erick Tryzelaarc9188c82013-03-27 00:34:491333 assert_eq!(
Erick Tryzelaar9bbf3842013-03-30 18:08:571334 do io::with_str_writer |wr| {
1335 let encoder = Encoder(wr);
1336 animal.encode(&encoder);
1337 },
1338 ~"\"Dog\""
1339 );
1340 assert_eq!(
1341 do io::with_str_writer |wr| {
1342 let encoder = PrettyEncoder(wr);
1343 animal.encode(&encoder);
1344 },
1345 ~"\"Dog\""
1346 );
1347
1348 let animal = Frog(~"Henry", 349);
1349 assert_eq!(
1350 do io::with_str_writer |wr| {
1351 let encoder = Encoder(wr);
1352 animal.encode(&encoder);
1353 },
1354 ~"[\"Frog\",\"Henry\",349]"
1355 );
1356 assert_eq!(
1357 do io::with_str_writer |wr| {
1358 let encoder = PrettyEncoder(wr);
1359 animal.encode(&encoder);
1360 },
Erick Tryzelaarc9188c82013-03-27 00:34:491361 ~"\
1362 [\n \
1363 \"Frog\",\n \
Erick Tryzelaar4d995e62013-03-27 07:14:521364 \"Henry\",\n \
1365 349\n\
Erick Tryzelaarc9188c82013-03-27 00:34:491366 ]"
1367 );
John Clementsc952c042013-02-08 23:36:401368 }
1369
1370 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001371 fn test_write_some() {
1372 let value = Some(~"jodhpurs");
1373 let s = do io::with_str_writer |wr| {
1374 let encoder = Encoder(wr);
1375 value.encode(&encoder);
1376 };
1377 assert_eq!(s, ~"\"jodhpurs\"");
John Clementsc952c042013-02-08 23:36:401378
Erick Tryzelaarc9188c82013-03-27 00:34:491379 let value = Some(~"jodhpurs");
1380 let s = do io::with_str_writer |wr| {
1381 let encoder = PrettyEncoder(wr);
1382 value.encode(&encoder);
1383 };
1384 assert_eq!(s, ~"\"jodhpurs\"");
1385 }
1386
1387 #[test]
Erick Tryzelaar6cf99fa2013-03-27 00:23:001388 fn test_write_none() {
1389 let value: Option<~str> = None;
1390 let s = do io::with_str_writer |wr| {
1391 let encoder = Encoder(wr);
1392 value.encode(&encoder);
1393 };
1394 assert_eq!(s, ~"null");
John Clementsf91160b2013-02-08 01:06:261395
Erick Tryzelaarc9188c82013-03-27 00:34:491396 let s = do io::with_str_writer |wr| {
1397 let encoder = Encoder(wr);
1398 value.encode(&encoder);
1399 };
1400 assert_eq!(s, ~"null");
1401 }
1402
1403 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321404 fn test_trailing_characters() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001405 assert_eq!(from_str(~"nulla"),
Patrick Waltond7e74b52013-03-06 21:58:021406 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001407 assert_eq!(from_str(~"truea"),
Patrick Waltond7e74b52013-03-06 21:58:021408 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001409 assert_eq!(from_str(~"falsea"),
Patrick Waltond7e74b52013-03-06 21:58:021410 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001411 assert_eq!(from_str(~"1a"),
Patrick Waltond7e74b52013-03-06 21:58:021412 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001413 assert_eq!(from_str(~"[]a"),
Patrick Waltond7e74b52013-03-06 21:58:021414 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001415 assert_eq!(from_str(~"{}a"),
Patrick Waltond7e74b52013-03-06 21:58:021416 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
Erick Tryzelaar012dec52012-02-26 00:39:321417 }
1418
1419 #[test]
1420 fn test_read_identifiers() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001421 assert_eq!(from_str(~"n"),
Patrick Waltond7e74b52013-03-06 21:58:021422 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001423 assert_eq!(from_str(~"nul"),
Patrick Waltond7e74b52013-03-06 21:58:021424 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321425
Erick Tryzelaar6cf99fa2013-03-27 00:23:001426 assert_eq!(from_str(~"t"),
Patrick Waltond7e74b52013-03-06 21:58:021427 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001428 assert_eq!(from_str(~"truz"),
Patrick Waltond7e74b52013-03-06 21:58:021429 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321430
Erick Tryzelaar6cf99fa2013-03-27 00:23:001431 assert_eq!(from_str(~"f"),
Patrick Waltond7e74b52013-03-06 21:58:021432 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001433 assert_eq!(from_str(~"faz"),
Patrick Waltond7e74b52013-03-06 21:58:021434 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321435
Erick Tryzelaar6cf99fa2013-03-27 00:23:001436 assert_eq!(from_str(~"null"), Ok(Null));
1437 assert_eq!(from_str(~"true"), Ok(Boolean(true)));
1438 assert_eq!(from_str(~"false"), Ok(Boolean(false)));
1439 assert_eq!(from_str(~" null "), Ok(Null));
1440 assert_eq!(from_str(~" true "), Ok(Boolean(true)));
1441 assert_eq!(from_str(~" false "), Ok(Boolean(false)));
Erick Tryzelaar012dec52012-02-26 00:39:321442 }
1443
1444 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421445 fn test_read_number() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001446 assert_eq!(from_str(~"+"),
Patrick Waltond7e74b52013-03-06 21:58:021447 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001448 assert_eq!(from_str(~"."),
Patrick Waltond7e74b52013-03-06 21:58:021449 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
Erick Tryzelaar012dec52012-02-26 00:39:321450
Erick Tryzelaar6cf99fa2013-03-27 00:23:001451 assert_eq!(from_str(~"-"),
Patrick Waltond7e74b52013-03-06 21:58:021452 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001453 assert_eq!(from_str(~"00"),
Patrick Waltond7e74b52013-03-06 21:58:021454 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001455 assert_eq!(from_str(~"1."),
Patrick Waltond7e74b52013-03-06 21:58:021456 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001457 assert_eq!(from_str(~"1e"),
Patrick Waltond7e74b52013-03-06 21:58:021458 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001459 assert_eq!(from_str(~"1e+"),
Patrick Waltond7e74b52013-03-06 21:58:021460 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"}));
Erick Tryzelaar012dec52012-02-26 00:39:321461
Erick Tryzelaar6cf99fa2013-03-27 00:23:001462 assert_eq!(from_str(~"3"), Ok(Number(3f)));
1463 assert_eq!(from_str(~"3.1"), Ok(Number(3.1f)));
1464 assert_eq!(from_str(~"-1.2"), Ok(Number(-1.2f)));
1465 assert_eq!(from_str(~"0.4"), Ok(Number(0.4f)));
1466 assert_eq!(from_str(~"0.4e5"), Ok(Number(0.4e5f)));
1467 assert_eq!(from_str(~"0.4e+15"), Ok(Number(0.4e15f)));
1468 assert_eq!(from_str(~"0.4e-01"), Ok(Number(0.4e-01f)));
1469 assert_eq!(from_str(~" 3 "), Ok(Number(3f)));
Erick Tryzelaar012dec52012-02-26 00:39:321470 }
1471
1472 #[test]
1473 fn test_read_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001474 assert_eq!(from_str(~"\""),
Patrick Waltond7e74b52013-03-06 21:58:021475 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"
1476 }));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001477 assert_eq!(from_str(~"\"lol"),
Patrick Waltond7e74b52013-03-06 21:58:021478 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"
1479 }));
Erick Tryzelaar012dec52012-02-26 00:39:321480
Erick Tryzelaar6cf99fa2013-03-27 00:23:001481 assert_eq!(from_str(~"\"\""), Ok(String(~"")));
1482 assert_eq!(from_str(~"\"foo\""), Ok(String(~"foo")));
1483 assert_eq!(from_str(~"\"\\\"\""), Ok(String(~"\"")));
1484 assert_eq!(from_str(~"\"\\b\""), Ok(String(~"\x08")));
1485 assert_eq!(from_str(~"\"\\n\""), Ok(String(~"\n")));
1486 assert_eq!(from_str(~"\"\\r\""), Ok(String(~"\r")));
1487 assert_eq!(from_str(~"\"\\t\""), Ok(String(~"\t")));
1488 assert_eq!(from_str(~" \"foo\" "), Ok(String(~"foo")));
Erick Tryzelaar012dec52012-02-26 00:39:321489 }
1490
1491 #[test]
Kevin Cantucf386182012-08-31 04:03:191492 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001493 assert_eq!(from_str(~"\"\\u12ab\""), Ok(String(~"\u12ab")));
1494 assert_eq!(from_str(~"\"\\uAB12\""), Ok(String(~"\uAB12")));
Kevin Cantucf386182012-08-31 04:03:191495 }
1496
1497 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321498 fn test_read_list() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001499 assert_eq!(from_str(~"["),
Patrick Waltond7e74b52013-03-06 21:58:021500 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001501 assert_eq!(from_str(~"[1"),
Patrick Waltond7e74b52013-03-06 21:58:021502 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001503 assert_eq!(from_str(~"[1,"),
Patrick Waltond7e74b52013-03-06 21:58:021504 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001505 assert_eq!(from_str(~"[1,]"),
Patrick Waltond7e74b52013-03-06 21:58:021506 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001507 assert_eq!(from_str(~"[6 7]"),
Patrick Waltond7e74b52013-03-06 21:58:021508 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"}));
Erick Tryzelaar012dec52012-02-26 00:39:321509
Erick Tryzelaar6cf99fa2013-03-27 00:23:001510 assert_eq!(from_str(~"[]"), Ok(List(~[])));
1511 assert_eq!(from_str(~"[ ]"), Ok(List(~[])));
1512 assert_eq!(from_str(~"[true]"), Ok(List(~[Boolean(true)])));
1513 assert_eq!(from_str(~"[ false ]"), Ok(List(~[Boolean(false)])));
1514 assert_eq!(from_str(~"[null]"), Ok(List(~[Null])));
1515 assert_eq!(from_str(~"[3, 1]"),
Patrick Waltond7e74b52013-03-06 21:58:021516 Ok(List(~[Number(3f), Number(1f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001517 assert_eq!(from_str(~"\n[3, 2]\n"),
Patrick Waltond7e74b52013-03-06 21:58:021518 Ok(List(~[Number(3f), Number(2f)])));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001519 assert_eq!(from_str(~"[2, [4, 1]]"),
Patrick Waltond7e74b52013-03-06 21:58:021520 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])])));
Erick Tryzelaar012dec52012-02-26 00:39:321521 }
1522
1523 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421524 fn test_read_object() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001525 assert_eq!(from_str(~"{"),
Patrick Waltond7e74b52013-03-06 21:58:021526 Err(Error {
1527 line: 1u,
1528 col: 2u,
1529 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001530 assert_eq!(from_str(~"{ "),
Patrick Waltond7e74b52013-03-06 21:58:021531 Err(Error {
1532 line: 1u,
1533 col: 3u,
1534 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001535 assert_eq!(from_str(~"{1"),
Patrick Waltond7e74b52013-03-06 21:58:021536 Err(Error {
1537 line: 1u,
1538 col: 2u,
1539 msg: @~"key must be a string"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001540 assert_eq!(from_str(~"{ \"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021541 Err(Error {
1542 line: 1u,
1543 col: 6u,
1544 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001545 assert_eq!(from_str(~"{\"a\""),
Patrick Waltond7e74b52013-03-06 21:58:021546 Err(Error {
1547 line: 1u,
1548 col: 5u,
1549 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001550 assert_eq!(from_str(~"{\"a\" "),
Patrick Waltond7e74b52013-03-06 21:58:021551 Err(Error {
1552 line: 1u,
1553 col: 6u,
1554 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321555
Erick Tryzelaar6cf99fa2013-03-27 00:23:001556 assert_eq!(from_str(~"{\"a\" 1"),
Patrick Waltond7e74b52013-03-06 21:58:021557 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001558 assert_eq!(from_str(~"{\"a\":"),
Patrick Waltond7e74b52013-03-06 21:58:021559 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001560 assert_eq!(from_str(~"{\"a\":1"),
Patrick Waltond7e74b52013-03-06 21:58:021561 Err(Error {
1562 line: 1u,
1563 col: 7u,
1564 msg: @~"EOF while parsing object"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001565 assert_eq!(from_str(~"{\"a\":1 1"),
Patrick Waltond7e74b52013-03-06 21:58:021566 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"}));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001567 assert_eq!(from_str(~"{\"a\":1,"),
Patrick Waltond7e74b52013-03-06 21:58:021568 Err(Error {
1569 line: 1u,
1570 col: 8u,
1571 msg: @~"EOF while parsing object"}));
Erick Tryzelaar012dec52012-02-26 00:39:321572
Erick Tryzelaar6cf99fa2013-03-27 00:23:001573 assert_eq!(result::unwrap(from_str(~"{}")), mk_object(~[]));
1574 assert_eq!(result::unwrap(from_str(~"{\"a\": 3}")),
Patrick Waltond7e74b52013-03-06 21:58:021575 mk_object(~[(~"a", Number(3.0f))]));
Erick Tryzelaar012dec52012-02-26 00:39:321576
Erick Tryzelaar6cf99fa2013-03-27 00:23:001577 assert_eq!(result::unwrap(from_str(
1578 ~"{ \"a\": null, \"b\" : true }")),
Erick Tryzelaar49d00b22012-09-24 16:55:421579 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421580 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021581 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001582 assert_eq!(result::unwrap(
1583 from_str(~"\n{ \"a\": null, \"b\" : true }\n")),
Erick Tryzelaar49d00b22012-09-24 16:55:421584 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421585 (~"a", Null),
Patrick Waltond7e74b52013-03-06 21:58:021586 (~"b", Boolean(true))]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001587 assert_eq!(result::unwrap(from_str(
1588 ~"{\"a\" : 1.0 ,\"b\": [ true ]}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421589 mk_object(~[
1590 (~"a", Number(1.0)),
1591 (~"b", List(~[Boolean(true)]))
Patrick Waltond7e74b52013-03-06 21:58:021592 ]));
Erick Tryzelaar6cf99fa2013-03-27 00:23:001593 assert_eq!(result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481594 ~"{" +
1595 ~"\"a\": 1.0, " +
1596 ~"\"b\": [" +
1597 ~"true," +
1598 ~"\"foo\\nbar\", " +
1599 ~"{ \"c\": {\"d\": null} } " +
1600 ~"]" +
Erick Tryzelaar6cf99fa2013-03-27 00:23:001601 ~"}")),
Erick Tryzelaar49d00b22012-09-24 16:55:421602 mk_object(~[
1603 (~"a", Number(1.0f)),
1604 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421605 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421606 String(~"foo\nbar"),
1607 mk_object(~[
1608 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561609 ])
1610 ]))
Patrick Waltond7e74b52013-03-06 21:58:021611 ]));
Erick Tryzelaar012dec52012-02-26 00:39:321612 }
1613
1614 #[test]
Erick Tryzelaarb10b8c32013-03-27 07:13:011615 fn test_read_none() {
1616 let decoder = Decoder(from_str(~"null").unwrap());
1617 let value: Option<~str> = Decodable::decode(&decoder);
1618 assert_eq!(value, None);
1619 }
1620
1621 #[test]
1622 fn test_read_some() {
1623 let decoder = Decoder(from_str(~"\"jodhpurs\"").unwrap());
1624 let value: Option<~str> = Decodable::decode(&decoder);
1625 assert_eq!(value, Some(~"jodhpurs"));
1626 }
1627
1628 #[test]
Erick Tryzelaar4e9a63f2013-03-27 00:42:011629 fn test_read_enum_no_args() {
1630 let decoder = Decoder(from_str(~"\"Dog\"").unwrap());
1631 let value: Animal = Decodable::decode(&decoder);
1632 assert_eq!(value, Dog);
1633 }
1634
1635 #[test]
1636 fn test_read_enum_multiple_args() {
1637 let decoder = Decoder(from_str(~"[\"Frog\",\"Henry\",349]").unwrap());
1638 let value: Animal = Decodable::decode(&decoder);
1639 assert_eq!(value, Frog(~"Henry", 349));
1640 }
1641
1642 #[test]
Erick Tryzelaard1a83e62013-03-29 16:04:351643 fn test_read_map() {
1644 let s = ~"{\"a\": \"Dog\", \"b\": [\"Frog\", \"Henry\", 349]}";
1645 let decoder = Decoder(from_str(s).unwrap());
Erick Tryzelaarbdef3f12013-03-29 16:10:311646 let mut map: LinearMap<~str, Animal> = Decodable::decode(&decoder);
Erick Tryzelaard1a83e62013-03-29 16:04:351647
Erick Tryzelaarbdef3f12013-03-29 16:10:311648 assert_eq!(map.pop(&~"a"), Some(Dog));
1649 assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349)));
Erick Tryzelaard1a83e62013-03-29 16:04:351650 }
1651
1652 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321653 fn test_multiline_errors() {
Erick Tryzelaar6cf99fa2013-03-27 00:23:001654 assert_eq!(from_str(~"{\n \"foo\":\n \"bar\""),
Patrick Waltond7e74b52013-03-06 21:58:021655 Err(Error {
1656 line: 3u,
1657 col: 8u,
1658 msg: @~"EOF while parsing object"}));
Brian Anderson6e27b272012-01-18 03:05:071659 }
1660}