blob: 0d3391c1867c243fc5dda9f46ebd4f2b51d79858 [file] [log] [blame]
Elly Jones656a2af2011-11-07 23:24:441// Rust JSON serialization library
2// Copyright (c) 2011 Google Inc.
Tim Chevalier8fc60af2012-10-05 02:58:313#[forbid(deprecated_mode)];
Kevin Cantuc43426e2012-09-13 05:09:554#[forbid(non_camel_case_types)];
Elly Jonesbd726262011-11-07 19:01:285
Gareth Daniel Smithbe014162012-07-04 21:53:126//! json serialization
Brian Anderson95521c42012-03-08 02:17:307
Patrick Walton22b87572012-09-08 01:53:148use core::cmp::{Eq, Ord};
Eric Holk135ebca2012-09-25 17:16:439use io::{WriterUtil, ReaderUtil};
Erick Tryzelaar49d00b22012-09-24 16:55:4210use send_map::linear;
Patrick Walton22b87572012-09-08 01:53:1411use sort::Sort;
Elly Jonesbd726262011-11-07 19:01:2812
Gareth Daniel Smithbe014162012-07-04 21:53:1213/// Represents a json value
Erick Tryzelaar49d00b22012-09-24 16:55:4214pub enum Json {
15 Number(float),
16 String(~str),
Ben Striegela605fd02012-08-11 14:08:4217 Boolean(bool),
Erick Tryzelaar49d00b22012-09-24 16:55:4218 List(List),
19 Object(~Object),
Ben Striegela605fd02012-08-11 14:08:4220 Null,
Elly Jonesbd726262011-11-07 19:01:2821}
22
Erick Tryzelaar49d00b22012-09-24 16:55:4223pub type List = ~[Json];
24pub type Object = linear::LinearMap<~str, Json>;
25
26pub struct Error {
Erick Tryzelaar012dec52012-02-26 00:39:3227 line: uint,
28 col: uint,
Michael Sullivan92743dc2012-07-14 05:57:4829 msg: @~str,
Kevin Cantud47cb102012-08-30 23:39:5630}
31
Kevin Cantuc43426e2012-09-13 05:09:5532fn escape_str(s: &str) -> ~str {
Michael Sullivan92743dc2012-07-14 05:57:4833 let mut escaped = ~"\"";
Niko Matsakis9cf271f2012-09-19 04:41:3734 for str::chars_each(s) |c| {
Brian Andersonecaf9e32012-08-06 19:34:0835 match c {
Brian Anderson025d8662012-08-04 02:59:0436 '"' => escaped += ~"\\\"",
37 '\\' => escaped += ~"\\\\",
38 '\x08' => escaped += ~"\\b",
39 '\x0c' => escaped += ~"\\f",
40 '\n' => escaped += ~"\\n",
41 '\r' => escaped += ~"\\r",
42 '\t' => escaped += ~"\\t",
43 _ => escaped += str::from_char(c)
Erick Tryzelaarb361f6c2012-06-13 00:20:5144 }
45 };
46
Michael Sullivan92743dc2012-07-14 05:57:4847 escaped += ~"\"";
Erick Tryzelaarb361f6c2012-06-13 00:20:5148
49 escaped
50}
51
Erick Tryzelaar49d00b22012-09-24 16:55:4252fn spaces(n: uint) -> ~str {
53 let mut ss = ~"";
Tim Chevalier5a8ba072012-10-11 21:12:5054 for n.times { str::push_str(&mut ss, " "); }
Erick Tryzelaar49d00b22012-09-24 16:55:4255 return ss;
56}
57
58pub struct Serializer {
59 priv wr: io::Writer,
60}
61
62pub fn Serializer(wr: io::Writer) -> Serializer {
63 Serializer { wr: wr }
64}
65
Erick Tryzelaareb626e72012-10-07 23:33:2066pub impl Serializer: serialization::Serializer {
Erick Tryzelaar49d00b22012-09-24 16:55:4267 fn emit_nil(&self) { self.wr.write_str("null") }
68
69 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
70 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
71 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
72 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
73 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
74
75 fn emit_int(&self, v: int) { self.emit_float(v as float); }
76 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
77 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
78 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
79 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
80
81 fn emit_bool(&self, v: bool) {
82 if v {
83 self.wr.write_str("true");
84 } else {
85 self.wr.write_str("false");
86 }
87 }
88
89 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
90 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
91 fn emit_float(&self, v: float) {
92 self.wr.write_str(float::to_str(v, 6u));
93 }
94
Erick Tryzelaar81423a32012-09-27 04:35:1395 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
96
97 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
98 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
99 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
100
101 fn emit_borrowed(&self, f: fn()) { f() }
102 fn emit_owned(&self, f: fn()) { f() }
103 fn emit_managed(&self, f: fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42104
105 fn emit_enum(&self, name: &str, f: fn()) {
106 if name != "option" { fail ~"only supports option enum" }
107 f()
108 }
109 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
110 if id == 0 {
111 self.emit_nil();
112 } else {
113 f()
114 }
115 }
116 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
117 f()
118 }
119
Erick Tryzelaar81423a32012-09-27 04:35:13120 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42121 self.wr.write_char('[');
122 f();
123 self.wr.write_char(']');
124 }
Erick Tryzelaar81423a32012-09-27 04:35:13125 fn emit_owned_vec(&self, len: uint, f: fn()) {
126 self.emit_borrowed_vec(len, f)
127 }
128 fn emit_managed_vec(&self, len: uint, f: fn()) {
129 self.emit_borrowed_vec(len, f)
130 }
Erick Tryzelaar49d00b22012-09-24 16:55:42131 fn emit_vec_elt(&self, idx: uint, f: fn()) {
132 if idx != 0 { self.wr.write_char(','); }
133 f()
134 }
135
Erick Tryzelaar49d00b22012-09-24 16:55:42136 fn emit_rec(&self, f: fn()) {
137 self.wr.write_char('{');
138 f();
139 self.wr.write_char('}');
140 }
Erick Tryzelaar81423a32012-09-27 04:35:13141 fn emit_struct(&self, _name: &str, f: fn()) {
142 self.wr.write_char('{');
143 f();
144 self.wr.write_char('}');
145 }
146 fn emit_field(&self, name: &str, idx: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42147 if idx != 0 { self.wr.write_char(','); }
148 self.wr.write_str(escape_str(name));
149 self.wr.write_char(':');
150 f();
151 }
Erick Tryzelaar81423a32012-09-27 04:35:13152
153 fn emit_tup(&self, len: uint, f: fn()) {
154 self.emit_borrowed_vec(len, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42155 }
156 fn emit_tup_elt(&self, idx: uint, f: fn()) {
157 self.emit_vec_elt(idx, f)
158 }
159}
160
161pub struct PrettySerializer {
162 priv wr: io::Writer,
163 priv mut indent: uint,
164}
165
166pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer {
167 PrettySerializer { wr: wr, indent: 0 }
168}
169
Erick Tryzelaareb626e72012-10-07 23:33:20170pub impl PrettySerializer: serialization::Serializer {
Erick Tryzelaar49d00b22012-09-24 16:55:42171 fn emit_nil(&self) { self.wr.write_str("null") }
172
173 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
174 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
175 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
176 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
177 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
178
179 fn emit_int(&self, v: int) { self.emit_float(v as float); }
180 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
181 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
182 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
183 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
184
185 fn emit_bool(&self, v: bool) {
186 if v {
187 self.wr.write_str("true");
188 } else {
189 self.wr.write_str("false");
190 }
191 }
192
193 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
194 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
195 fn emit_float(&self, v: float) {
196 self.wr.write_str(float::to_str(v, 6u));
197 }
198
Erick Tryzelaar81423a32012-09-27 04:35:13199 fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
200
201 fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
202 fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
203 fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
204
205 fn emit_borrowed(&self, f: fn()) { f() }
206 fn emit_owned(&self, f: fn()) { f() }
207 fn emit_managed(&self, f: fn()) { f() }
Erick Tryzelaar49d00b22012-09-24 16:55:42208
209 fn emit_enum(&self, name: &str, f: fn()) {
210 if name != "option" { fail ~"only supports option enum" }
211 f()
212 }
213 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
214 if id == 0 {
215 self.emit_nil();
216 } else {
217 f()
218 }
219 }
220 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
221 f()
222 }
223
Erick Tryzelaar81423a32012-09-27 04:35:13224 fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
Erick Tryzelaar49d00b22012-09-24 16:55:42225 self.wr.write_char('[');
226 self.indent += 2;
227 f();
228 self.indent -= 2;
229 self.wr.write_char(']');
230 }
Erick Tryzelaar81423a32012-09-27 04:35:13231 fn emit_owned_vec(&self, len: uint, f: fn()) {
232 self.emit_borrowed_vec(len, f)
233 }
234 fn emit_managed_vec(&self, len: uint, f: fn()) {
235 self.emit_borrowed_vec(len, f)
236 }
Erick Tryzelaar49d00b22012-09-24 16:55:42237 fn emit_vec_elt(&self, idx: uint, f: fn()) {
238 if idx == 0 {
239 self.wr.write_char('\n');
240 } else {
241 self.wr.write_str(",\n");
242 }
243 self.wr.write_str(spaces(self.indent));
244 f()
245 }
246
Erick Tryzelaar49d00b22012-09-24 16:55:42247 fn emit_rec(&self, f: fn()) {
248 self.wr.write_char('{');
249 self.indent += 2;
250 f();
251 self.indent -= 2;
252 self.wr.write_char('}');
253 }
Erick Tryzelaar81423a32012-09-27 04:35:13254 fn emit_struct(&self, _name: &str, f: fn()) {
255 self.emit_rec(f)
256 }
257 fn emit_field(&self, name: &str, 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 self.wr.write_str(escape_str(name));
265 self.wr.write_str(": ");
266 f();
267 }
268 fn emit_tup(&self, sz: uint, f: fn()) {
Erick Tryzelaar81423a32012-09-27 04:35:13269 self.emit_borrowed_vec(sz, f);
Erick Tryzelaar49d00b22012-09-24 16:55:42270 }
271 fn emit_tup_elt(&self, idx: uint, f: fn()) {
272 self.emit_vec_elt(idx, f)
273 }
274}
275
Erick Tryzelaareb626e72012-10-07 23:33:20276pub impl Json: serialization::Serializable {
277 fn serialize<S: serialization::Serializer>(&self, s: &S) {
Erick Tryzelaar81423a32012-09-27 04:35:13278 match *self {
279 Number(v) => v.serialize(s),
280 String(ref v) => v.serialize(s),
281 Boolean(v) => v.serialize(s),
282 List(v) => v.serialize(s),
283 Object(ref v) => {
284 do s.emit_rec || {
285 let mut idx = 0;
286 for v.each |key, value| {
287 do s.emit_field(*key, idx) {
288 value.serialize(s);
289 }
290 idx += 1;
Erick Tryzelaar49d00b22012-09-24 16:55:42291 }
Erick Tryzelaar49d00b22012-09-24 16:55:42292 }
Erick Tryzelaar81423a32012-09-27 04:35:13293 },
294 Null => s.emit_nil(),
Erick Tryzelaar49d00b22012-09-24 16:55:42295 }
Erick Tryzelaar49d00b22012-09-24 16:55:42296 }
297}
298
299/// Serializes a json value into a io::writer
300pub fn to_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar81423a32012-09-27 04:35:13301 json.serialize(&Serializer(wr))
Erick Tryzelaar49d00b22012-09-24 16:55:42302}
303
Gareth Daniel Smithbe014162012-07-04 21:53:12304/// Serializes a json value into a string
Tim Chevalier5a8ba072012-10-11 21:12:50305pub pure fn to_str(json: &Json) -> ~str unsafe {
306 // ugh, should be safe
Erick Tryzelaar49d00b22012-09-24 16:55:42307 io::with_str_writer(|wr| to_writer(wr, json))
Elly Jonesbd726262011-11-07 19:01:28308}
309
Erick Tryzelaar49d00b22012-09-24 16:55:42310/// Serializes a json value into a io::writer
311pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
Erick Tryzelaar81423a32012-09-27 04:35:13312 json.serialize(&PrettySerializer(wr))
Kevin Cantud47cb102012-08-30 23:39:56313}
314
Erick Tryzelaar49d00b22012-09-24 16:55:42315/// Serializes a json value into a string
316pub fn to_pretty_str(json: &Json) -> ~str {
317 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40318}
319
Erick Tryzelaar49d00b22012-09-24 16:55:42320pub struct Parser {
321 priv rdr: io::Reader,
322 priv mut ch: char,
323 priv mut line: uint,
324 priv mut col: uint,
325}
326
327/// Deserializes a json value from an io::reader
328pub fn Parser(rdr: io::Reader) -> Parser {
329 Parser {
330 rdr: rdr,
331 ch: rdr.read_char(),
Tim Chevalier90d06b82012-09-19 05:35:42332 line: 1,
333 col: 1,
Erick Tryzelaar49d00b22012-09-24 16:55:42334 }
335}
336
337pub impl Parser {
338 fn parse() -> Result<Json, Error> {
339 match move self.parse_value() {
340 Ok(move value) => {
341 // Skip trailing whitespaces.
342 self.parse_whitespace();
343 // Make sure there is no trailing characters.
344 if self.eof() {
Tim Chevalier90d06b82012-09-19 05:35:42345 Ok(move value)
Erick Tryzelaar49d00b22012-09-24 16:55:42346 } else {
347 self.error(~"trailing characters")
348 }
349 }
350 Err(move e) => Err(e)
351 }
352 }
353}
354
355priv impl Parser {
Erick Tryzelaar012dec52012-02-26 00:39:32356 fn eof() -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28357
Erick Tryzelaar012dec52012-02-26 00:39:32358 fn bump() {
359 self.ch = self.rdr.read_char();
360
361 if self.ch == '\n' {
362 self.line += 1u;
363 self.col = 1u;
364 } else {
365 self.col += 1u;
366 }
Elly Jonesbd726262011-11-07 19:01:28367 }
368
Erick Tryzelaar012dec52012-02-26 00:39:32369 fn next_char() -> char {
370 self.bump();
371 self.ch
Elly Jonesbd726262011-11-07 19:01:28372 }
373
Tim Chevalierf33539e2012-10-03 19:21:48374 fn error<T>(msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42375 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28376 }
Elly Jonesbd726262011-11-07 19:01:28377
Ben Striegela605fd02012-08-11 14:08:42378 fn parse_value() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32379 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28380
Brian Andersonb3559362012-08-02 00:30:05381 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32382
Brian Andersonecaf9e32012-08-06 19:34:08383 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42384 'n' => self.parse_ident(~"ull", Null),
385 't' => self.parse_ident(~"rue", Boolean(true)),
386 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05387 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42388 '"' =>
389 match move self.parse_str() {
390 Ok(move s) => Ok(String(s)),
391 Err(move e) => Err(e),
392 },
Brian Anderson025d8662012-08-04 02:59:04393 '[' => self.parse_list(),
394 '{' => self.parse_object(),
395 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32396 }
397 }
398
399 fn parse_whitespace() {
400 while char::is_whitespace(self.ch) { self.bump(); }
401 }
402
Tim Chevalier8fc60af2012-10-05 02:58:31403 fn parse_ident(ident: &str, value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07404 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32405 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42406 Ok(move value)
Erick Tryzelaar012dec52012-02-26 00:39:32407 } else {
Michael Sullivan92743dc2012-07-14 05:57:48408 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32409 }
410 }
411
Ben Striegela605fd02012-08-11 14:08:42412 fn parse_number() -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56413 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32414
415 if self.ch == '-' {
416 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00417 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28418 }
Elly Jonesbd726262011-11-07 19:01:28419
Brian Andersonecaf9e32012-08-06 19:34:08420 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31421 Ok(res) => res,
422 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32423 };
424
425 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08426 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31427 Ok(r) => res = r,
428 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28429 }
Elly Jonesbd726262011-11-07 19:01:28430 }
Erick Tryzelaar012dec52012-02-26 00:39:32431
432 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08433 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31434 Ok(r) => res = r,
435 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32436 }
437 }
438
Erick Tryzelaar49d00b22012-09-24 16:55:42439 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28440 }
441
Ben Striegela605fd02012-08-11 14:08:42442 fn parse_integer() -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56443 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32444
Brian Andersonecaf9e32012-08-06 19:34:08445 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04446 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32447 self.bump();
448
449 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08450 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05451 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04452 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32453 }
454 }
Brian Anderson80c4f742012-09-02 01:38:05455 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32456 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08457 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05458 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32459 res *= 10f;
460 res += ((self.ch as int) - ('0' as int)) as float;
461
462 self.bump();
463 }
Brian Anderson025d8662012-08-04 02:59:04464 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32465 }
466 }
467 }
Brian Anderson025d8662012-08-04 02:59:04468 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32469 }
470
Brian Anderson0c6e4702012-08-26 23:54:31471 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28472 }
473
Ben Striegela605fd02012-08-11 14:08:42474 fn parse_decimal(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32475 self.bump();
476
477 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08478 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05479 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04480 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32481 }
482
Niko Matsakis6b358752012-03-14 18:03:56483 let mut res = res;
484 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32485 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08486 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05487 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00488 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32489 res += (((self.ch as int) - ('0' as int)) as float) * dec;
490
491 self.bump();
492 }
Brian Anderson025d8662012-08-04 02:59:04493 _ => break
Elly Jonesbd726262011-11-07 19:01:28494 }
Elly Jonesbd726262011-11-07 19:01:28495 }
Elly Jonesbd726262011-11-07 19:01:28496
Brian Anderson0c6e4702012-08-26 23:54:31497 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32498 }
499
Ben Striegela605fd02012-08-11 14:08:42500 fn parse_exponent(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32501 self.bump();
502
Niko Matsakis6b358752012-03-14 18:03:56503 let mut res = res;
504 let mut exp = 0u;
505 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32506
Brian Andersonecaf9e32012-08-06 19:34:08507 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04508 '+' => self.bump(),
509 '-' => { self.bump(); neg_exp = true; }
510 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32511 }
512
513 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08514 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05515 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04516 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32517 }
518
519 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08520 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05521 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32522 exp *= 10u;
523 exp += (self.ch as uint) - ('0' as uint);
524
525 self.bump();
526 }
Brian Anderson025d8662012-08-04 02:59:04527 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32528 }
529 }
530
531 let exp = float::pow_with_uint(10u, exp);
532 if neg_exp {
533 res /= exp;
534 } else {
535 res *= exp;
536 }
537
Brian Anderson0c6e4702012-08-26 23:54:31538 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32539 }
540
Erick Tryzelaar49d00b22012-09-24 16:55:42541 fn parse_str() -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56542 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48543 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32544
545 while !self.eof() {
546 self.bump();
547
548 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08549 match self.ch {
Tim Chevalier5a8ba072012-10-11 21:12:50550 '"' => str::push_char(&mut res, '"'),
551 '\\' => str::push_char(&mut res, '\\'),
552 '/' => str::push_char(&mut res, '/'),
553 'b' => str::push_char(&mut res, '\x08'),
554 'f' => str::push_char(&mut res, '\x0c'),
555 'n' => str::push_char(&mut res, '\n'),
556 'r' => str::push_char(&mut res, '\r'),
557 't' => str::push_char(&mut res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04558 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32559 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56560 let mut i = 0u;
561 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32562 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08563 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05564 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10565 n = n * 16u + (self.ch as uint)
566 - ('0' as uint);
567 },
568 'a' | 'A' => n = n * 16u + 10u,
569 'b' | 'B' => n = n * 16u + 11u,
570 'c' | 'C' => n = n * 16u + 12u,
571 'd' | 'D' => n = n * 16u + 13u,
572 'e' | 'E' => n = n * 16u + 14u,
573 'f' | 'F' => n = n * 16u + 15u,
574 _ => return self.error(
575 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32576 }
Niko Matsakis6b358752012-03-14 18:03:56577 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32578 }
579
580 // Error out if we didn't parse 4 digits.
581 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10582 return self.error(
583 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32584 }
585
Tim Chevalier5a8ba072012-10-11 21:12:50586 str::push_char(&mut res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32587 }
Brian Anderson025d8662012-08-04 02:59:04588 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32589 }
590 escape = false;
591 } else if self.ch == '\\' {
592 escape = true;
593 } else {
594 if self.ch == '"' {
595 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42596 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32597 }
Tim Chevalier5a8ba072012-10-11 21:12:50598 str::push_char(&mut res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32599 }
600 }
601
Michael Sullivan92743dc2012-07-14 05:57:48602 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32603 }
604
Ben Striegela605fd02012-08-11 14:08:42605 fn parse_list() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32606 self.bump();
607 self.parse_whitespace();
608
Michael Sullivan98e161f2012-06-29 23:26:56609 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32610
611 if self.ch == ']' {
612 self.bump();
Tim Chevalier90d06b82012-09-19 05:35:42613 return Ok(List(move values));
Erick Tryzelaar012dec52012-02-26 00:39:32614 }
615
Tim Chevalier35400e12012-03-11 04:34:17616 loop {
Erick Tryzelaar49d00b22012-09-24 16:55:42617 match move self.parse_value() {
Tim Chevalier90d06b82012-09-19 05:35:42618 Ok(move v) => values.push(move v),
Erick Tryzelaar49d00b22012-09-24 16:55:42619 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32620 }
621
622 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17623 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05624 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17625 }
Erick Tryzelaar012dec52012-02-26 00:39:32626
Brian Andersonecaf9e32012-08-06 19:34:08627 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04628 ',' => self.bump(),
Tim Chevalier90d06b82012-09-19 05:35:42629 ']' => { self.bump(); return Ok(List(move values)); }
Brian Anderson025d8662012-08-04 02:59:04630 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32631 }
Tim Chevalier35400e12012-03-11 04:34:17632 };
Erick Tryzelaar012dec52012-02-26 00:39:32633 }
634
Ben Striegela605fd02012-08-11 14:08:42635 fn parse_object() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32636 self.bump();
637 self.parse_whitespace();
638
Erick Tryzelaar49d00b22012-09-24 16:55:42639 let mut values = ~linear::LinearMap();
Erick Tryzelaar012dec52012-02-26 00:39:32640
641 if self.ch == '}' {
642 self.bump();
Tim Chevalier90d06b82012-09-19 05:35:42643 return Ok(Object(move values));
Erick Tryzelaar012dec52012-02-26 00:39:32644 }
645
646 while !self.eof() {
647 self.parse_whitespace();
648
649 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05650 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32651 }
652
Erick Tryzelaar49d00b22012-09-24 16:55:42653 let key = match move self.parse_str() {
654 Ok(move key) => key,
655 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32656 };
657
658 self.parse_whitespace();
659
660 if self.ch != ':' {
661 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05662 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32663 }
664 self.bump();
665
Erick Tryzelaar49d00b22012-09-24 16:55:42666 match move self.parse_value() {
Tim Chevalier90d06b82012-09-19 05:35:42667 Ok(move value) => { values.insert(key, move value); }
Erick Tryzelaar49d00b22012-09-24 16:55:42668 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32669 }
670 self.parse_whitespace();
671
Brian Andersonecaf9e32012-08-06 19:34:08672 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04673 ',' => self.bump(),
Tim Chevalier90d06b82012-09-19 05:35:42674 '}' => { self.bump(); return Ok(Object(move values)); }
Brian Anderson025d8662012-08-04 02:59:04675 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32676 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05677 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32678 }
679 }
680 }
681
Brian Andersonb3559362012-08-02 00:30:05682 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28683 }
684}
685
Gareth Daniel Smithbe014162012-07-04 21:53:12686/// Deserializes a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42687pub fn from_reader(rdr: io::Reader) -> Result<Json, Error> {
688 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28689}
690
Gareth Daniel Smithbe014162012-07-04 21:53:12691/// Deserializes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42692pub fn from_str(s: &str) -> Result<Json, Error> {
693 do io::with_str_reader(s) |rdr| {
694 from_reader(rdr)
695 }
Erick Tryzelaar012dec52012-02-26 00:39:32696}
697
Erick Tryzelaar49d00b22012-09-24 16:55:42698pub struct Deserializer {
699 priv json: Json,
700 priv mut stack: ~[&Json],
701}
702
703pub fn Deserializer(rdr: io::Reader) -> Result<Deserializer, Error> {
704 match move from_reader(rdr) {
705 Ok(move json) => {
Tim Chevalier90d06b82012-09-19 05:35:42706 let des = Deserializer { json: move json, stack: ~[] };
Erick Tryzelaar49d00b22012-09-24 16:55:42707 Ok(move des)
708 }
709 Err(move e) => Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32710 }
Elly Jonesbd726262011-11-07 19:01:28711}
Brian Anderson6e27b272012-01-18 03:05:07712
Erick Tryzelaar49d00b22012-09-24 16:55:42713priv impl Deserializer {
Niko Matsakis67a8e712012-09-27 00:33:34714 fn peek(&self) -> &self/Json {
715 if self.stack.len() == 0 { self.stack.push(&self.json); }
Erick Tryzelaar49d00b22012-09-24 16:55:42716 vec::last(self.stack)
717 }
718
Niko Matsakis67a8e712012-09-27 00:33:34719 fn pop(&self) -> &self/Json {
720 if self.stack.len() == 0 { self.stack.push(&self.json); }
Niko Matsakis21519bc2012-09-28 05:20:47721 self.stack.pop()
Erick Tryzelaar49d00b22012-09-24 16:55:42722 }
723}
724
Erick Tryzelaareb626e72012-10-07 23:33:20725pub impl Deserializer: serialization::Deserializer {
Erick Tryzelaar49d00b22012-09-24 16:55:42726 fn read_nil(&self) -> () {
727 debug!("read_nil");
728 match *self.pop() {
729 Null => (),
730 _ => fail ~"not a null"
731 }
732 }
733
734 fn read_u64(&self) -> u64 { self.read_float() as u64 }
735 fn read_u32(&self) -> u32 { self.read_float() as u32 }
736 fn read_u16(&self) -> u16 { self.read_float() as u16 }
737 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
738 fn read_uint(&self) -> uint { self.read_float() as uint }
739
740 fn read_i64(&self) -> i64 { self.read_float() as i64 }
741 fn read_i32(&self) -> i32 { self.read_float() as i32 }
742 fn read_i16(&self) -> i16 { self.read_float() as i16 }
743 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
744 fn read_int(&self) -> int { self.read_float() as int }
745
746 fn read_bool(&self) -> bool {
747 debug!("read_bool");
748 match *self.pop() {
749 Boolean(b) => b,
750 _ => fail ~"not a boolean"
751 }
752 }
753
754 fn read_f64(&self) -> f64 { self.read_float() as f64 }
755 fn read_f32(&self) -> f32 { self.read_float() as f32 }
756 fn read_float(&self) -> float {
757 debug!("read_float");
758 match *self.pop() {
759 Number(f) => f,
760 _ => fail ~"not a number"
761 }
762 }
763
Erick Tryzelaar81423a32012-09-27 04:35:13764 fn read_char(&self) -> char {
765 let v = str::chars(self.read_owned_str());
766 if v.len() != 1 { fail ~"string must have one character" }
767 v[0]
768 }
769
770 fn read_owned_str(&self) -> ~str {
771 debug!("read_owned_str");
Erick Tryzelaar49d00b22012-09-24 16:55:42772 match *self.pop() {
773 String(ref s) => copy *s,
774 _ => fail ~"not a string"
775 }
776 }
777
Erick Tryzelaar81423a32012-09-27 04:35:13778 fn read_managed_str(&self) -> @str {
779 // FIXME(#3604): There's no way to convert from a ~str to a @str.
780 fail ~"read_managed_str()";
781 }
782
783 fn read_owned<T>(&self, f: fn() -> T) -> T {
784 debug!("read_owned()");
785 f()
786 }
787
788 fn read_managed<T>(&self, f: fn() -> T) -> T {
789 debug!("read_managed()");
790 f()
791 }
792
Tim Chevalier9ff95e22012-10-01 19:36:06793 fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
Erick Tryzelaar49d00b22012-09-24 16:55:42794 debug!("read_enum(%s)", name);
795 if name != ~"option" { fail ~"only supports the option enum" }
796 f()
797 }
798
799 fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
800 debug!("read_enum_variant()");
801 let idx = match *self.peek() {
802 Null => 0,
803 _ => 1,
804 };
805 f(idx)
806 }
807
808 fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
809 debug!("read_enum_variant_arg(idx=%u)", idx);
810 if idx != 0 { fail ~"unknown index" }
811 f()
812 }
813
Erick Tryzelaar81423a32012-09-27 04:35:13814 fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
815 debug!("read_owned_vec()");
816 let len = match *self.peek() {
817 List(list) => list.len(),
818 _ => fail ~"not a list",
819 };
820 let res = f(len);
821 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42822 move res
Erick Tryzelaar81423a32012-09-27 04:35:13823 }
824
825 fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
826 debug!("read_owned_vec()");
Erick Tryzelaar49d00b22012-09-24 16:55:42827 let len = match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34828 List(ref list) => list.len(),
Erick Tryzelaar49d00b22012-09-24 16:55:42829 _ => fail ~"not a list",
830 };
831 let res = f(len);
832 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42833 move res
Erick Tryzelaar49d00b22012-09-24 16:55:42834 }
835
836 fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
837 debug!("read_vec_elt(idx=%u)", idx);
838 match *self.peek() {
839 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34840 // FIXME(#3148)---should be inferred
841 let list: &self/~[Json] = list;
842
843 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42844 f()
845 }
846 _ => fail ~"not a list",
847 }
848 }
849
Erick Tryzelaar49d00b22012-09-24 16:55:42850 fn read_rec<T>(&self, f: fn() -> T) -> T {
851 debug!("read_rec()");
852 let value = f();
853 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42854 move value
Erick Tryzelaar49d00b22012-09-24 16:55:42855 }
856
Erick Tryzelaar81423a32012-09-27 04:35:13857 fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
858 debug!("read_struct()");
859 let value = f();
860 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42861 move value
Erick Tryzelaar81423a32012-09-27 04:35:13862 }
863
864 fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
865 debug!("read_rec_field(%s, idx=%u)", name, idx);
Erick Tryzelaar49d00b22012-09-24 16:55:42866 let top = self.peek();
867 match *top {
868 Object(ref obj) => {
869 // FIXME(#3148) This hint should not be necessary.
870 let obj: &self/~Object = obj;
871
Erick Tryzelaar81423a32012-09-27 04:35:13872 match obj.find_ref(&name.to_unique()) {
873 None => fail fmt!("no such field: %s", name),
Erick Tryzelaar49d00b22012-09-24 16:55:42874 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34875 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42876 f()
877 }
878 }
879 }
880 Number(_) => fail ~"num",
881 String(_) => fail ~"str",
882 Boolean(_) => fail ~"bool",
883 List(_) => fail fmt!("list: %?", top),
884 Null => fail ~"null",
885
886 //_ => fail fmt!("not an object: %?", *top)
887 }
888 }
889
Erick Tryzelaar81423a32012-09-27 04:35:13890 fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
891 debug!("read_tup(len=%u)", len);
Erick Tryzelaar49d00b22012-09-24 16:55:42892 let value = f();
893 self.pop();
Tim Chevalier90d06b82012-09-19 05:35:42894 move value
Erick Tryzelaar49d00b22012-09-24 16:55:42895 }
896
897 fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
898 debug!("read_tup_elt(idx=%u)", idx);
899 match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34900 List(ref list) => {
901 // FIXME(#3148)---should be inferred
902 let list: &self/~[Json] = list;
903 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42904 f()
905 }
906 _ => fail ~"not a list"
907 }
908 }
909}
910
911impl Json : Eq {
912 pure fn eq(other: &Json) -> bool {
913 // XXX: This is ugly because matching on references is broken, and
914 // we can't match on dereferenced tuples without a copy.
915 match self {
916 Number(f0) =>
917 match *other { Number(f1) => f0 == f1, _ => false },
Brian Andersonbc9efaa2012-09-28 07:22:18918 String(ref s0) =>
919 match *other { String(ref s1) => s0 == s1, _ => false },
Erick Tryzelaar49d00b22012-09-24 16:55:42920 Boolean(b0) =>
921 match *other { Boolean(b1) => b0 == b1, _ => false },
922 Null =>
923 match *other { Null => true, _ => false },
924 List(v0) =>
925 match *other { List(v1) => v0 == v1, _ => false },
926 Object(ref d0) => {
927 match *other {
928 Object(ref d1) => {
929 if d0.len() == d1.len() {
930 let mut equal = true;
931 for d0.each |k, v0| {
932 match d1.find_ref(k) {
933 Some(v1) if v0 == v1 => { },
934 _ => { equal = false; break }
935 }
936 };
937 equal
938 } else {
939 false
940 }
941 }
942 _ => false
943 }
944 }
945 }
946 }
947 pure fn ne(other: &Json) -> bool { !self.eq(other) }
948}
949
Patrick Walton22b87572012-09-08 01:53:14950/// Test if two json values are less than one another
Erick Tryzelaar49d00b22012-09-24 16:55:42951impl Json : Ord {
952 pure fn lt(other: &Json) -> bool {
953 match self {
954 Number(f0) => {
955 match *other {
956 Number(f1) => f0 < f1,
957 String(_) | Boolean(_) | List(_) | Object(_) |
958 Null => true
959 }
Patrick Walton22b87572012-09-08 01:53:14960 }
Patrick Walton22b87572012-09-08 01:53:14961
Brian Andersonbc9efaa2012-09-28 07:22:18962 String(ref s0) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42963 match *other {
964 Number(_) => false,
Brian Andersonbc9efaa2012-09-28 07:22:18965 String(ref s1) => s0 < s1,
Erick Tryzelaar49d00b22012-09-24 16:55:42966 Boolean(_) | List(_) | Object(_) | Null => true
967 }
Patrick Walton22b87572012-09-08 01:53:14968 }
Patrick Walton22b87572012-09-08 01:53:14969
Erick Tryzelaar49d00b22012-09-24 16:55:42970 Boolean(b0) => {
971 match *other {
972 Number(_) | String(_) => false,
973 Boolean(b1) => b0 < b1,
974 List(_) | Object(_) | Null => true
975 }
Patrick Walton22b87572012-09-08 01:53:14976 }
Patrick Walton22b87572012-09-08 01:53:14977
Erick Tryzelaar49d00b22012-09-24 16:55:42978 List(l0) => {
979 match *other {
980 Number(_) | String(_) | Boolean(_) => false,
981 List(l1) => l0 < l1,
982 Object(_) | Null => true
983 }
Patrick Walton22b87572012-09-08 01:53:14984 }
Patrick Walton22b87572012-09-08 01:53:14985
Brian Andersonbc9efaa2012-09-28 07:22:18986 Object(ref d0) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42987 match *other {
988 Number(_) | String(_) | Boolean(_) | List(_) => false,
Brian Andersonbc9efaa2012-09-28 07:22:18989 Object(ref d1) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42990 unsafe {
991 let mut d0_flat = ~[];
992 let mut d1_flat = ~[];
993
994 // XXX: this is horribly inefficient...
995 for d0.each |k, v| {
Niko Matsakis67a8e712012-09-27 00:33:34996 d0_flat.push((@copy *k, @copy *v));
Erick Tryzelaar49d00b22012-09-24 16:55:42997 }
Patrick Walton22b87572012-09-08 01:53:14998 d0_flat.qsort();
999
Erick Tryzelaar49d00b22012-09-24 16:55:421000 for d1.each |k, v| {
Niko Matsakis67a8e712012-09-27 00:33:341001 d1_flat.push((@copy *k, @copy *v));
Erick Tryzelaar49d00b22012-09-24 16:55:421002 }
Patrick Walton22b87572012-09-08 01:53:141003 d1_flat.qsort();
1004
Erick Tryzelaar49d00b22012-09-24 16:55:421005 d0_flat < d1_flat
1006 }
Patrick Walton22b87572012-09-08 01:53:141007 }
Erick Tryzelaar49d00b22012-09-24 16:55:421008 Null => true
Patrick Walton22b87572012-09-08 01:53:141009 }
Patrick Walton22b87572012-09-08 01:53:141010 }
Patrick Walton22b87572012-09-08 01:53:141011
Erick Tryzelaar49d00b22012-09-24 16:55:421012 Null => {
1013 match *other {
1014 Number(_) | String(_) | Boolean(_) | List(_) |
1015 Object(_) =>
1016 false,
1017 Null => true
1018 }
Patrick Walton22b87572012-09-08 01:53:141019 }
1020 }
1021 }
Erick Tryzelaar49d00b22012-09-24 16:55:421022 pure fn le(other: &Json) -> bool { !(*other).lt(&self) }
1023 pure fn ge(other: &Json) -> bool { !self.lt(other) }
1024 pure fn gt(other: &Json) -> bool { (*other).lt(&self) }
Patrick Walton22b87572012-09-08 01:53:141025}
1026
Patrick Walton9117dcb2012-09-20 01:00:261027impl Error : Eq {
1028 pure fn eq(other: &Error) -> bool {
Erick Tryzelaar49d00b22012-09-24 16:55:421029 self.line == other.line &&
1030 self.col == other.col &&
1031 self.msg == other.msg
Patrick Walton9117dcb2012-09-20 01:00:261032 }
1033 pure fn ne(other: &Error) -> bool { !self.eq(other) }
1034}
Patrick Walton96534362012-08-27 23:26:351035
Ben Striegela605fd02012-08-11 14:08:421036trait ToJson { fn to_json() -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:321037
Ben Striegela605fd02012-08-11 14:08:421038impl Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421039 fn to_json() -> Json { copy self }
Erick Tryzelaared5af702012-05-28 19:10:321040}
1041
Ben Striegela605fd02012-08-11 14:08:421042impl @Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421043 fn to_json() -> Json { (*self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:541044}
1045
Ben Striegela605fd02012-08-11 14:08:421046impl int: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421047 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541048}
1049
Ben Striegela605fd02012-08-11 14:08:421050impl i8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421051 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321052}
1053
Ben Striegela605fd02012-08-11 14:08:421054impl i16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421055 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321056}
1057
Ben Striegela605fd02012-08-11 14:08:421058impl i32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421059 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321060}
1061
Ben Striegela605fd02012-08-11 14:08:421062impl i64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421063 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321064}
1065
Ben Striegela605fd02012-08-11 14:08:421066impl uint: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421067 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541068}
1069
Ben Striegela605fd02012-08-11 14:08:421070impl u8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421071 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321072}
1073
Ben Striegela605fd02012-08-11 14:08:421074impl u16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421075 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321076}
1077
Ben Striegela605fd02012-08-11 14:08:421078impl u32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421079 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321080}
1081
Ben Striegela605fd02012-08-11 14:08:421082impl u64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421083 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321084}
1085
Ben Striegela605fd02012-08-11 14:08:421086impl float: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421087 fn to_json() -> Json { Number(self) }
Erick Tryzelaared5af702012-05-28 19:10:321088}
1089
Ben Striegela605fd02012-08-11 14:08:421090impl f32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421091 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321092}
1093
Ben Striegela605fd02012-08-11 14:08:421094impl f64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421095 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321096}
1097
Ben Striegela605fd02012-08-11 14:08:421098impl (): ToJson {
1099 fn to_json() -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321100}
1101
Ben Striegela605fd02012-08-11 14:08:421102impl bool: ToJson {
1103 fn to_json() -> Json { Boolean(self) }
Erick Tryzelaared5af702012-05-28 19:10:321104}
1105
Ben Striegela605fd02012-08-11 14:08:421106impl ~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421107 fn to_json() -> Json { String(copy self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511108}
1109
Ben Striegela605fd02012-08-11 14:08:421110impl @~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421111 fn to_json() -> Json { String(copy *self) }
Erick Tryzelaared5af702012-05-28 19:10:321112}
1113
Ben Striegela605fd02012-08-11 14:08:421114impl <A: ToJson, B: ToJson> (A, B): ToJson {
1115 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081116 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181117 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421118 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561119 }
1120 }
Erick Tryzelaared5af702012-05-28 19:10:321121 }
1122}
1123
Ben Striegela605fd02012-08-11 14:08:421124impl <A: ToJson, B: ToJson, C: ToJson> (A, B, C): ToJson {
Ben Striegela605fd02012-08-11 14:08:421125 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081126 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181127 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421128 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561129 }
1130 }
Erick Tryzelaared5af702012-05-28 19:10:321131 }
1132}
1133
Ben Striegela605fd02012-08-11 14:08:421134impl <A: ToJson> ~[A]: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421135 fn to_json() -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321136}
1137
Erick Tryzelaar49d00b22012-09-24 16:55:421138impl <A: ToJson Copy> linear::LinearMap<~str, A>: ToJson {
Ben Striegela605fd02012-08-11 14:08:421139 fn to_json() -> Json {
Erick Tryzelaar49d00b22012-09-24 16:55:421140 let mut d = linear::LinearMap();
Brian Andersond1fc2b52012-06-30 23:19:071141 for self.each() |key, value| {
Erick Tryzelaar49d00b22012-09-24 16:55:421142 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321143 }
Erick Tryzelaar49d00b22012-09-24 16:55:421144 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321145 }
1146}
1147
Erick Tryzelaar49d00b22012-09-24 16:55:421148/*
1149impl <A: ToJson Copy> @std::map::HashMap<~str, A>: ToJson {
1150 fn to_json() -> Json {
1151 let mut d = linear::LinearMap();
1152 for self.each_ref |key, value| {
1153 d.insert(copy *key, value.to_json());
1154 }
1155 Object(~d)
1156 }
1157}
1158*/
1159
Ben Striegela605fd02012-08-11 14:08:421160impl <A: ToJson> Option<A>: ToJson {
1161 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081162 match self {
Ben Striegela605fd02012-08-11 14:08:421163 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181164 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321165 }
1166 }
1167}
1168
Ben Striegela605fd02012-08-11 14:08:421169impl Json: to_str::ToStr {
Tim Chevalier5a8ba072012-10-11 21:12:501170 pure fn to_str() -> ~str { to_str(&self) }
Erick Tryzelaared5af702012-05-28 19:10:321171}
1172
Ben Striegela605fd02012-08-11 14:08:421173impl Error: to_str::ToStr {
Tim Chevalier5a8ba072012-10-11 21:12:501174 pure fn to_str() -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521175 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381176 }
1177}
1178
Brian Anderson6e27b272012-01-18 03:05:071179#[cfg(test)]
1180mod tests {
Erick Tryzelaar49d00b22012-09-24 16:55:421181 fn mk_object(items: &[(~str, Json)]) -> Json {
1182 let mut d = ~linear::LinearMap();
Erick Tryzelaar012dec52012-02-26 00:39:321183
Erick Tryzelaar49d00b22012-09-24 16:55:421184 for items.each |item| {
1185 match *item {
Tim Chevalier90d06b82012-09-19 05:35:421186 (copy key, copy value) => { d.insert(key, move value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421187 }
Erick Tryzelaar012dec52012-02-26 00:39:321188 };
1189
Tim Chevalier90d06b82012-09-19 05:35:421190 Object(move d)
Brian Anderson6e27b272012-01-18 03:05:071191 }
1192
1193 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321194 fn test_write_null() {
Erick Tryzelaar49d00b22012-09-24 16:55:421195 assert to_str(&Null) == ~"null";
Brian Anderson6e27b272012-01-18 03:05:071196 }
1197
1198 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421199 fn test_write_number() {
1200 assert to_str(&Number(3f)) == ~"3";
1201 assert to_str(&Number(3.1f)) == ~"3.1";
1202 assert to_str(&Number(-1.5f)) == ~"-1.5";
1203 assert to_str(&Number(0.5f)) == ~"0.5";
Brian Anderson6e27b272012-01-18 03:05:071204 }
1205
1206 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321207 fn test_write_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421208 assert to_str(&String(~"")) == ~"\"\"";
1209 assert to_str(&String(~"foo")) == ~"\"foo\"";
Brian Anderson6e27b272012-01-18 03:05:071210 }
1211
1212 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321213 fn test_write_bool() {
Erick Tryzelaar49d00b22012-09-24 16:55:421214 assert to_str(&Boolean(true)) == ~"true";
1215 assert to_str(&Boolean(false)) == ~"false";
Brian Anderson6e27b272012-01-18 03:05:071216 }
1217
1218 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321219 fn test_write_list() {
Erick Tryzelaar49d00b22012-09-24 16:55:421220 assert to_str(&List(~[])) == ~"[]";
1221 assert to_str(&List(~[Boolean(true)])) == ~"[true]";
1222 assert to_str(&List(~[
Ben Striegela605fd02012-08-11 14:08:421223 Boolean(false),
1224 Null,
Erick Tryzelaar49d00b22012-09-24 16:55:421225 List(~[String(~"foo\nbar"), Number(3.5f)])
1226 ])) == ~"[false,null,[\"foo\\nbar\",3.5]]";
Erick Tryzelaar012dec52012-02-26 00:39:321227 }
1228
1229 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421230 fn test_write_object() {
1231 assert to_str(&mk_object(~[])) == ~"{}";
1232 assert to_str(&mk_object(~[(~"a", Boolean(true))]))
1233 == ~"{\"a\":true}";
1234 let a = mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421235 (~"a", Boolean(true)),
Erick Tryzelaar49d00b22012-09-24 16:55:421236 (~"b", List(~[
1237 mk_object(~[(~"c", String(~"\x0c\r"))]),
1238 mk_object(~[(~"d", String(~""))])
Michael Sullivan98e161f2012-06-29 23:26:561239 ]))
Graydon Hoare11871b82012-08-30 23:27:151240 ]);
Erick Tryzelaar49d00b22012-09-24 16:55:421241 // We can't compare the strings directly because the object fields be
1242 // printed in a different order.
1243 let b = result::unwrap(from_str(to_str(&a)));
Graydon Hoare11871b82012-08-30 23:27:151244 assert a == b;
Erick Tryzelaar012dec52012-02-26 00:39:321245 }
1246
1247 #[test]
1248 fn test_trailing_characters() {
Michael Sullivan92743dc2012-07-14 05:57:481249 assert from_str(~"nulla") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421250 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481251 assert from_str(~"truea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421252 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481253 assert from_str(~"falsea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421254 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481255 assert from_str(~"1a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421256 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481257 assert from_str(~"[]a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421258 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481259 assert from_str(~"{}a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421260 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Erick Tryzelaar012dec52012-02-26 00:39:321261 }
1262
1263 #[test]
1264 fn test_read_identifiers() {
Michael Sullivan92743dc2012-07-14 05:57:481265 assert from_str(~"n") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421266 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481267 assert from_str(~"nul") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421268 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321269
Michael Sullivan92743dc2012-07-14 05:57:481270 assert from_str(~"t") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421271 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481272 assert from_str(~"truz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421273 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321274
Michael Sullivan92743dc2012-07-14 05:57:481275 assert from_str(~"f") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421276 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481277 assert from_str(~"faz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421278 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321279
Ben Striegela605fd02012-08-11 14:08:421280 assert from_str(~"null") == Ok(Null);
1281 assert from_str(~"true") == Ok(Boolean(true));
1282 assert from_str(~"false") == Ok(Boolean(false));
1283 assert from_str(~" null ") == Ok(Null);
1284 assert from_str(~" true ") == Ok(Boolean(true));
1285 assert from_str(~" false ") == Ok(Boolean(false));
Erick Tryzelaar012dec52012-02-26 00:39:321286 }
1287
1288 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421289 fn test_read_number() {
Michael Sullivan92743dc2012-07-14 05:57:481290 assert from_str(~"+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421291 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481292 assert from_str(~".") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421293 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321294
Michael Sullivan92743dc2012-07-14 05:57:481295 assert from_str(~"-") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421296 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481297 assert from_str(~"00") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421298 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481299 assert from_str(~"1.") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421300 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481301 assert from_str(~"1e") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421302 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481303 assert from_str(~"1e+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421304 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"});
Erick Tryzelaar012dec52012-02-26 00:39:321305
Erick Tryzelaar49d00b22012-09-24 16:55:421306 assert from_str(~"3") == Ok(Number(3f));
1307 assert from_str(~"3.1") == Ok(Number(3.1f));
1308 assert from_str(~"-1.2") == Ok(Number(-1.2f));
1309 assert from_str(~"0.4") == Ok(Number(0.4f));
1310 assert from_str(~"0.4e5") == Ok(Number(0.4e5f));
1311 assert from_str(~"0.4e+15") == Ok(Number(0.4e15f));
1312 assert from_str(~"0.4e-01") == Ok(Number(0.4e-01f));
1313 assert from_str(~" 3 ") == Ok(Number(3f));
Erick Tryzelaar012dec52012-02-26 00:39:321314 }
1315
1316 #[test]
1317 fn test_read_str() {
Michael Sullivan92743dc2012-07-14 05:57:481318 assert from_str(~"\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421319 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"});
Michael Sullivan92743dc2012-07-14 05:57:481320 assert from_str(~"\"lol") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421321 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"});
Erick Tryzelaar012dec52012-02-26 00:39:321322
Erick Tryzelaar49d00b22012-09-24 16:55:421323 assert from_str(~"\"\"") == Ok(String(~""));
1324 assert from_str(~"\"foo\"") == Ok(String(~"foo"));
1325 assert from_str(~"\"\\\"\"") == Ok(String(~"\""));
1326 assert from_str(~"\"\\b\"") == Ok(String(~"\x08"));
1327 assert from_str(~"\"\\n\"") == Ok(String(~"\n"));
1328 assert from_str(~"\"\\r\"") == Ok(String(~"\r"));
1329 assert from_str(~"\"\\t\"") == Ok(String(~"\t"));
1330 assert from_str(~" \"foo\" ") == Ok(String(~"foo"));
Erick Tryzelaar012dec52012-02-26 00:39:321331 }
1332
1333 #[test]
Kevin Cantucf386182012-08-31 04:03:191334 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421335 assert from_str(~"\"\\u12ab\"") == Ok(String(~"\u12ab"));
1336 assert from_str(~"\"\\uAB12\"") == Ok(String(~"\uAB12"));
Kevin Cantucf386182012-08-31 04:03:191337 }
1338
1339 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321340 fn test_read_list() {
Michael Sullivan92743dc2012-07-14 05:57:481341 assert from_str(~"[") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421342 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481343 assert from_str(~"[1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421344 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"});
Michael Sullivan92743dc2012-07-14 05:57:481345 assert from_str(~"[1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421346 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481347 assert from_str(~"[1,]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421348 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481349 assert from_str(~"[6 7]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421350 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"});
Erick Tryzelaar012dec52012-02-26 00:39:321351
Erick Tryzelaar49d00b22012-09-24 16:55:421352 assert from_str(~"[]") == Ok(List(~[]));
1353 assert from_str(~"[ ]") == Ok(List(~[]));
1354 assert from_str(~"[true]") == Ok(List(~[Boolean(true)]));
1355 assert from_str(~"[ false ]") == Ok(List(~[Boolean(false)]));
1356 assert from_str(~"[null]") == Ok(List(~[Null]));
1357 assert from_str(~"[3, 1]") == Ok(List(~[Number(3f), Number(1f)]));
1358 assert from_str(~"\n[3, 2]\n") == Ok(List(~[Number(3f), Number(2f)]));
Michael Sullivan92743dc2012-07-14 05:57:481359 assert from_str(~"[2, [4, 1]]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421360 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])]));
Erick Tryzelaar012dec52012-02-26 00:39:321361 }
1362
1363 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421364 fn test_read_object() {
Michael Sullivan92743dc2012-07-14 05:57:481365 assert from_str(~"{") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421366 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481367 assert from_str(~"{ ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421368 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481369 assert from_str(~"{1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421370 Err(Error {line: 1u, col: 2u, msg: @~"key must be a string"});
Michael Sullivan92743dc2012-07-14 05:57:481371 assert from_str(~"{ \"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421372 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481373 assert from_str(~"{\"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421374 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481375 assert from_str(~"{\"a\" ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421376 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321377
Michael Sullivan92743dc2012-07-14 05:57:481378 assert from_str(~"{\"a\" 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421379 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"});
Michael Sullivan92743dc2012-07-14 05:57:481380 assert from_str(~"{\"a\":") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421381 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481382 assert from_str(~"{\"a\":1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421383 Err(Error {line: 1u, col: 7u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481384 assert from_str(~"{\"a\":1 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421385 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"});
Michael Sullivan92743dc2012-07-14 05:57:481386 assert from_str(~"{\"a\":1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421387 Err(Error {line: 1u, col: 8u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321388
Erick Tryzelaar49d00b22012-09-24 16:55:421389 assert result::unwrap(from_str(~"{}")) == mk_object(~[]);
1390 assert result::unwrap(from_str(~"{\"a\": 3}")) ==
1391 mk_object(~[(~"a", Number(3.0f))]);
Erick Tryzelaar012dec52012-02-26 00:39:321392
Erick Tryzelaar49d00b22012-09-24 16:55:421393 assert result::unwrap(from_str(~"{ \"a\": null, \"b\" : true }")) ==
1394 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421395 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421396 (~"b", Boolean(true))]);
1397 assert result::unwrap(
1398 from_str(~"\n{ \"a\": null, \"b\" : true }\n")) ==
1399 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421400 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421401 (~"b", Boolean(true))]);
1402 assert result::unwrap(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")) ==
1403 mk_object(~[
1404 (~"a", Number(1.0)),
1405 (~"b", List(~[Boolean(true)]))
1406 ]);
1407 assert result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481408 ~"{" +
1409 ~"\"a\": 1.0, " +
1410 ~"\"b\": [" +
1411 ~"true," +
1412 ~"\"foo\\nbar\", " +
1413 ~"{ \"c\": {\"d\": null} } " +
1414 ~"]" +
Erick Tryzelaar49d00b22012-09-24 16:55:421415 ~"}")) ==
1416 mk_object(~[
1417 (~"a", Number(1.0f)),
1418 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421419 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421420 String(~"foo\nbar"),
1421 mk_object(~[
1422 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561423 ])
1424 ]))
Erick Tryzelaar49d00b22012-09-24 16:55:421425 ]);
Erick Tryzelaar012dec52012-02-26 00:39:321426 }
1427
1428 #[test]
1429 fn test_multiline_errors() {
Michael Sullivan92743dc2012-07-14 05:57:481430 assert from_str(~"{\n \"foo\":\n \"bar\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421431 Err(Error {line: 3u, col: 8u, msg: @~"EOF while parsing object"});
Brian Anderson6e27b272012-01-18 03:05:071432 }
1433}