blob: 247c13396d0ea067478816820d1c4a6aec5e4843 [file] [log] [blame]
Elly Jones656a2af2011-11-07 23:24:441// Rust JSON serialization library
2// Copyright (c) 2011 Google Inc.
Kevin Cantuc43426e2012-09-13 05:09:553#[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};
Patrick Walton2d690ae2012-09-04 18:23:539use result::{Result, Ok, Err};
Eric Holk135ebca2012-09-25 17:16:4310use io::{WriterUtil, ReaderUtil};
Brian Andersoncb7a5392012-09-10 22:38:2811use map::HashMap;
12use map::Map;
Erick Tryzelaar49d00b22012-09-24 16:55:4213use send_map::linear;
Patrick Walton22b87572012-09-08 01:53:1414use sort::Sort;
Elly Jonesbd726262011-11-07 19:01:2815
Gareth Daniel Smithbe014162012-07-04 21:53:1216/// Represents a json value
Erick Tryzelaar49d00b22012-09-24 16:55:4217pub enum Json {
18 Number(float),
19 String(~str),
Ben Striegela605fd02012-08-11 14:08:4220 Boolean(bool),
Erick Tryzelaar49d00b22012-09-24 16:55:4221 List(List),
22 Object(~Object),
Ben Striegela605fd02012-08-11 14:08:4223 Null,
Elly Jonesbd726262011-11-07 19:01:2824}
25
Erick Tryzelaar49d00b22012-09-24 16:55:4226pub type List = ~[Json];
27pub type Object = linear::LinearMap<~str, Json>;
28
29pub struct Error {
Erick Tryzelaar012dec52012-02-26 00:39:3230 line: uint,
31 col: uint,
Michael Sullivan92743dc2012-07-14 05:57:4832 msg: @~str,
Kevin Cantud47cb102012-08-30 23:39:5633}
34
Kevin Cantuc43426e2012-09-13 05:09:5535fn escape_str(s: &str) -> ~str {
Michael Sullivan92743dc2012-07-14 05:57:4836 let mut escaped = ~"\"";
Niko Matsakis9cf271f2012-09-19 04:41:3737 for str::chars_each(s) |c| {
Brian Andersonecaf9e32012-08-06 19:34:0838 match c {
Brian Anderson025d8662012-08-04 02:59:0439 '"' => escaped += ~"\\\"",
40 '\\' => escaped += ~"\\\\",
41 '\x08' => escaped += ~"\\b",
42 '\x0c' => escaped += ~"\\f",
43 '\n' => escaped += ~"\\n",
44 '\r' => escaped += ~"\\r",
45 '\t' => escaped += ~"\\t",
46 _ => escaped += str::from_char(c)
Erick Tryzelaarb361f6c2012-06-13 00:20:5147 }
48 };
49
Michael Sullivan92743dc2012-07-14 05:57:4850 escaped += ~"\"";
Erick Tryzelaarb361f6c2012-06-13 00:20:5151
52 escaped
53}
54
Erick Tryzelaar49d00b22012-09-24 16:55:4255fn spaces(n: uint) -> ~str {
56 let mut ss = ~"";
57 for n.times { str::push_str(&ss, " "); }
58 return ss;
59}
60
61pub struct Serializer {
62 priv wr: io::Writer,
63}
64
65pub fn Serializer(wr: io::Writer) -> Serializer {
66 Serializer { wr: wr }
67}
68
69pub impl Serializer: serialization2::Serializer {
70 fn emit_nil(&self) { self.wr.write_str("null") }
71
72 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
73 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
74 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
75 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
76 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
77
78 fn emit_int(&self, v: int) { self.emit_float(v as float); }
79 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
80 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
81 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
82 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
83
84 fn emit_bool(&self, v: bool) {
85 if v {
86 self.wr.write_str("true");
87 } else {
88 self.wr.write_str("false");
89 }
90 }
91
92 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
93 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
94 fn emit_float(&self, v: float) {
95 self.wr.write_str(float::to_str(v, 6u));
96 }
97
98 fn emit_str(&self, v: &str) {
99 let s = escape_str(v);
100 self.wr.write_str(s);
101 }
102
103 fn emit_enum(&self, name: &str, f: fn()) {
104 if name != "option" { fail ~"only supports option enum" }
105 f()
106 }
107 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
108 if id == 0 {
109 self.emit_nil();
110 } else {
111 f()
112 }
113 }
114 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
115 f()
116 }
117
118 fn emit_vec(&self, _len: uint, f: fn()) {
119 self.wr.write_char('[');
120 f();
121 self.wr.write_char(']');
122 }
123
124 fn emit_vec_elt(&self, idx: uint, f: fn()) {
125 if idx != 0 { self.wr.write_char(','); }
126 f()
127 }
128
129 fn emit_box(&self, f: fn()) { f() }
130 fn emit_uniq(&self, f: fn()) { f() }
131 fn emit_rec(&self, f: fn()) {
132 self.wr.write_char('{');
133 f();
134 self.wr.write_char('}');
135 }
136 fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
137 if idx != 0 { self.wr.write_char(','); }
138 self.wr.write_str(escape_str(name));
139 self.wr.write_char(':');
140 f();
141 }
142 fn emit_tup(&self, sz: uint, f: fn()) {
143 self.emit_vec(sz, f);
144 }
145 fn emit_tup_elt(&self, idx: uint, f: fn()) {
146 self.emit_vec_elt(idx, f)
147 }
148}
149
150pub struct PrettySerializer {
151 priv wr: io::Writer,
152 priv mut indent: uint,
153}
154
155pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer {
156 PrettySerializer { wr: wr, indent: 0 }
157}
158
159pub impl PrettySerializer: serialization2::Serializer {
160 fn emit_nil(&self) { self.wr.write_str("null") }
161
162 fn emit_uint(&self, v: uint) { self.emit_float(v as float); }
163 fn emit_u64(&self, v: u64) { self.emit_float(v as float); }
164 fn emit_u32(&self, v: u32) { self.emit_float(v as float); }
165 fn emit_u16(&self, v: u16) { self.emit_float(v as float); }
166 fn emit_u8(&self, v: u8) { self.emit_float(v as float); }
167
168 fn emit_int(&self, v: int) { self.emit_float(v as float); }
169 fn emit_i64(&self, v: i64) { self.emit_float(v as float); }
170 fn emit_i32(&self, v: i32) { self.emit_float(v as float); }
171 fn emit_i16(&self, v: i16) { self.emit_float(v as float); }
172 fn emit_i8(&self, v: i8) { self.emit_float(v as float); }
173
174 fn emit_bool(&self, v: bool) {
175 if v {
176 self.wr.write_str("true");
177 } else {
178 self.wr.write_str("false");
179 }
180 }
181
182 fn emit_f64(&self, v: f64) { self.emit_float(v as float); }
183 fn emit_f32(&self, v: f32) { self.emit_float(v as float); }
184 fn emit_float(&self, v: float) {
185 self.wr.write_str(float::to_str(v, 6u));
186 }
187
188 fn emit_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
189
190 fn emit_enum(&self, name: &str, f: fn()) {
191 if name != "option" { fail ~"only supports option enum" }
192 f()
193 }
194 fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) {
195 if id == 0 {
196 self.emit_nil();
197 } else {
198 f()
199 }
200 }
201 fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) {
202 f()
203 }
204
205 fn emit_vec(&self, _len: uint, f: fn()) {
206 self.wr.write_char('[');
207 self.indent += 2;
208 f();
209 self.indent -= 2;
210 self.wr.write_char(']');
211 }
212
213 fn emit_vec_elt(&self, idx: uint, f: fn()) {
214 if idx == 0 {
215 self.wr.write_char('\n');
216 } else {
217 self.wr.write_str(",\n");
218 }
219 self.wr.write_str(spaces(self.indent));
220 f()
221 }
222
223 fn emit_box(&self, f: fn()) { f() }
224 fn emit_uniq(&self, f: fn()) { f() }
225 fn emit_rec(&self, f: fn()) {
226 self.wr.write_char('{');
227 self.indent += 2;
228 f();
229 self.indent -= 2;
230 self.wr.write_char('}');
231 }
232 fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
233 if idx == 0 {
234 self.wr.write_char('\n');
235 } else {
236 self.wr.write_str(",\n");
237 }
238 self.wr.write_str(spaces(self.indent));
239 self.wr.write_str(escape_str(name));
240 self.wr.write_str(": ");
241 f();
242 }
243 fn emit_tup(&self, sz: uint, f: fn()) {
244 self.emit_vec(sz, f);
245 }
246 fn emit_tup_elt(&self, idx: uint, f: fn()) {
247 self.emit_vec_elt(idx, f)
248 }
249}
250
251pub fn to_serializer<S: serialization2::Serializer>(ser: &S, json: &Json) {
252 match *json {
253 Number(f) => ser.emit_float(f),
Brian Andersonbc9efaa2012-09-28 07:22:18254 String(ref s) => ser.emit_str(*s),
Erick Tryzelaar49d00b22012-09-24 16:55:42255 Boolean(b) => ser.emit_bool(b),
256 List(v) => {
257 do ser.emit_vec(v.len()) || {
258 for v.eachi |i, elt| {
259 ser.emit_vec_elt(i, || to_serializer(ser, elt))
260 }
261 }
262 }
Brian Andersonbc9efaa2012-09-28 07:22:18263 Object(ref o) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42264 do ser.emit_rec || {
265 let mut idx = 0;
266 for o.each |key, value| {
267 do ser.emit_rec_field(*key, idx) {
268 to_serializer(ser, value);
269 }
270 idx += 1;
271 }
272 }
273 }
274 Null => ser.emit_nil(),
275 }
276}
277
278/// Serializes a json value into a io::writer
279pub fn to_writer(wr: io::Writer, json: &Json) {
280 to_serializer(&Serializer(wr), json)
281}
282
Gareth Daniel Smithbe014162012-07-04 21:53:12283/// Serializes a json value into a string
Erick Tryzelaar49d00b22012-09-24 16:55:42284pub fn to_str(json: &Json) -> ~str {
285 io::with_str_writer(|wr| to_writer(wr, json))
Elly Jonesbd726262011-11-07 19:01:28286}
287
Erick Tryzelaar49d00b22012-09-24 16:55:42288/// Serializes a json value into a io::writer
289pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
290 to_serializer(&PrettySerializer(wr), json)
Kevin Cantud47cb102012-08-30 23:39:56291}
292
Erick Tryzelaar49d00b22012-09-24 16:55:42293/// Serializes a json value into a string
294pub fn to_pretty_str(json: &Json) -> ~str {
295 io::with_str_writer(|wr| to_pretty_writer(wr, json))
Patrick Waltondb020ab2012-07-11 22:00:40296}
297
Erick Tryzelaar49d00b22012-09-24 16:55:42298pub struct Parser {
299 priv rdr: io::Reader,
300 priv mut ch: char,
301 priv mut line: uint,
302 priv mut col: uint,
303}
304
305/// Deserializes a json value from an io::reader
306pub fn Parser(rdr: io::Reader) -> Parser {
307 Parser {
308 rdr: rdr,
309 ch: rdr.read_char(),
310 line: 1u,
311 col: 1u,
312 }
313}
314
315pub impl Parser {
316 fn parse() -> Result<Json, Error> {
317 match move self.parse_value() {
318 Ok(move value) => {
319 // Skip trailing whitespaces.
320 self.parse_whitespace();
321 // Make sure there is no trailing characters.
322 if self.eof() {
323 Ok(value)
324 } else {
325 self.error(~"trailing characters")
326 }
327 }
328 Err(move e) => Err(e)
329 }
330 }
331}
332
333priv impl Parser {
Erick Tryzelaar012dec52012-02-26 00:39:32334 fn eof() -> bool { self.ch == -1 as char }
Elly Jonesbd726262011-11-07 19:01:28335
Erick Tryzelaar012dec52012-02-26 00:39:32336 fn bump() {
337 self.ch = self.rdr.read_char();
338
339 if self.ch == '\n' {
340 self.line += 1u;
341 self.col = 1u;
342 } else {
343 self.col += 1u;
344 }
Elly Jonesbd726262011-11-07 19:01:28345 }
346
Erick Tryzelaar012dec52012-02-26 00:39:32347 fn next_char() -> char {
348 self.bump();
349 self.ch
Elly Jonesbd726262011-11-07 19:01:28350 }
351
Ben Striegela605fd02012-08-11 14:08:42352 fn error<T>(+msg: ~str) -> Result<T, Error> {
Erick Tryzelaar49d00b22012-09-24 16:55:42353 Err(Error { line: self.line, col: self.col, msg: @msg })
Elly Jonesbd726262011-11-07 19:01:28354 }
Elly Jonesbd726262011-11-07 19:01:28355
Ben Striegela605fd02012-08-11 14:08:42356 fn parse_value() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32357 self.parse_whitespace();
Elly Jonesbd726262011-11-07 19:01:28358
Brian Andersonb3559362012-08-02 00:30:05359 if self.eof() { return self.error(~"EOF while parsing value"); }
Erick Tryzelaar012dec52012-02-26 00:39:32360
Brian Andersonecaf9e32012-08-06 19:34:08361 match self.ch {
Ben Striegela605fd02012-08-11 14:08:42362 'n' => self.parse_ident(~"ull", Null),
363 't' => self.parse_ident(~"rue", Boolean(true)),
364 'f' => self.parse_ident(~"alse", Boolean(false)),
Brian Anderson80c4f742012-09-02 01:38:05365 '0' .. '9' | '-' => self.parse_number(),
Erick Tryzelaar49d00b22012-09-24 16:55:42366 '"' =>
367 match move self.parse_str() {
368 Ok(move s) => Ok(String(s)),
369 Err(move e) => Err(e),
370 },
Brian Anderson025d8662012-08-04 02:59:04371 '[' => self.parse_list(),
372 '{' => self.parse_object(),
373 _ => self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32374 }
375 }
376
377 fn parse_whitespace() {
378 while char::is_whitespace(self.ch) { self.bump(); }
379 }
380
Erick Tryzelaar49d00b22012-09-24 16:55:42381 fn parse_ident(ident: ~str, +value: Json) -> Result<Json, Error> {
Brian Andersond1fc2b52012-06-30 23:19:07382 if str::all(ident, |c| c == self.next_char()) {
Erick Tryzelaar012dec52012-02-26 00:39:32383 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42384 Ok(move value)
Erick Tryzelaar012dec52012-02-26 00:39:32385 } else {
Michael Sullivan92743dc2012-07-14 05:57:48386 self.error(~"invalid syntax")
Erick Tryzelaar012dec52012-02-26 00:39:32387 }
388 }
389
Ben Striegela605fd02012-08-11 14:08:42390 fn parse_number() -> Result<Json, Error> {
Niko Matsakis6b358752012-03-14 18:03:56391 let mut neg = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32392
393 if self.ch == '-' {
394 self.bump();
Marijn Haverbeke4f826d82011-12-16 09:11:00395 neg = -1f;
Elly Jonesbd726262011-11-07 19:01:28396 }
Elly Jonesbd726262011-11-07 19:01:28397
Brian Andersonecaf9e32012-08-06 19:34:08398 let mut res = match self.parse_integer() {
Brian Anderson0c6e4702012-08-26 23:54:31399 Ok(res) => res,
400 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32401 };
402
403 if self.ch == '.' {
Brian Andersonecaf9e32012-08-06 19:34:08404 match self.parse_decimal(res) {
Brian Anderson0c6e4702012-08-26 23:54:31405 Ok(r) => res = r,
406 Err(e) => return Err(e)
Elly Jonesbd726262011-11-07 19:01:28407 }
Elly Jonesbd726262011-11-07 19:01:28408 }
Erick Tryzelaar012dec52012-02-26 00:39:32409
410 if self.ch == 'e' || self.ch == 'E' {
Brian Andersonecaf9e32012-08-06 19:34:08411 match self.parse_exponent(res) {
Brian Anderson0c6e4702012-08-26 23:54:31412 Ok(r) => res = r,
413 Err(e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32414 }
415 }
416
Erick Tryzelaar49d00b22012-09-24 16:55:42417 Ok(Number(neg * res))
Elly Jonesbd726262011-11-07 19:01:28418 }
419
Ben Striegela605fd02012-08-11 14:08:42420 fn parse_integer() -> Result<float, Error> {
Niko Matsakis6b358752012-03-14 18:03:56421 let mut res = 0f;
Erick Tryzelaar012dec52012-02-26 00:39:32422
Brian Andersonecaf9e32012-08-06 19:34:08423 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04424 '0' => {
Erick Tryzelaar012dec52012-02-26 00:39:32425 self.bump();
426
427 // There can be only one leading '0'.
Brian Andersonecaf9e32012-08-06 19:34:08428 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05429 '0' .. '9' => return self.error(~"invalid number"),
Brian Anderson025d8662012-08-04 02:59:04430 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32431 }
432 }
Brian Anderson80c4f742012-09-02 01:38:05433 '1' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32434 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08435 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05436 '0' .. '9' => {
Erick Tryzelaar012dec52012-02-26 00:39:32437 res *= 10f;
438 res += ((self.ch as int) - ('0' as int)) as float;
439
440 self.bump();
441 }
Brian Anderson025d8662012-08-04 02:59:04442 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32443 }
444 }
445 }
Brian Anderson025d8662012-08-04 02:59:04446 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32447 }
448
Brian Anderson0c6e4702012-08-26 23:54:31449 Ok(res)
Elly Jonesbd726262011-11-07 19:01:28450 }
451
Ben Striegela605fd02012-08-11 14:08:42452 fn parse_decimal(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32453 self.bump();
454
455 // Make sure a digit follows the decimal place.
Brian Andersonecaf9e32012-08-06 19:34:08456 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05457 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04458 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32459 }
460
Niko Matsakis6b358752012-03-14 18:03:56461 let mut res = res;
462 let mut dec = 1f;
Erick Tryzelaar012dec52012-02-26 00:39:32463 while !self.eof() {
Brian Andersonecaf9e32012-08-06 19:34:08464 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05465 '0' .. '9' => {
Marijn Haverbeke4f826d82011-12-16 09:11:00466 dec /= 10f;
Erick Tryzelaar012dec52012-02-26 00:39:32467 res += (((self.ch as int) - ('0' as int)) as float) * dec;
468
469 self.bump();
470 }
Brian Anderson025d8662012-08-04 02:59:04471 _ => break
Elly Jonesbd726262011-11-07 19:01:28472 }
Elly Jonesbd726262011-11-07 19:01:28473 }
Elly Jonesbd726262011-11-07 19:01:28474
Brian Anderson0c6e4702012-08-26 23:54:31475 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32476 }
477
Ben Striegela605fd02012-08-11 14:08:42478 fn parse_exponent(res: float) -> Result<float, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32479 self.bump();
480
Niko Matsakis6b358752012-03-14 18:03:56481 let mut res = res;
482 let mut exp = 0u;
483 let mut neg_exp = false;
Erick Tryzelaar012dec52012-02-26 00:39:32484
Brian Andersonecaf9e32012-08-06 19:34:08485 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04486 '+' => self.bump(),
487 '-' => { self.bump(); neg_exp = true; }
488 _ => ()
Erick Tryzelaar012dec52012-02-26 00:39:32489 }
490
491 // Make sure a digit follows the exponent place.
Brian Andersonecaf9e32012-08-06 19:34:08492 match self.ch {
Brian Anderson80c4f742012-09-02 01:38:05493 '0' .. '9' => (),
Brian Anderson025d8662012-08-04 02:59:04494 _ => return self.error(~"invalid number")
Erick Tryzelaar012dec52012-02-26 00:39:32495 }
496
497 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 exp *= 10u;
501 exp += (self.ch as uint) - ('0' as uint);
502
503 self.bump();
504 }
Brian Anderson025d8662012-08-04 02:59:04505 _ => break
Erick Tryzelaar012dec52012-02-26 00:39:32506 }
507 }
508
509 let exp = float::pow_with_uint(10u, exp);
510 if neg_exp {
511 res /= exp;
512 } else {
513 res *= exp;
514 }
515
Brian Anderson0c6e4702012-08-26 23:54:31516 Ok(res)
Erick Tryzelaar012dec52012-02-26 00:39:32517 }
518
Erick Tryzelaar49d00b22012-09-24 16:55:42519 fn parse_str() -> Result<~str, Error> {
Niko Matsakis6b358752012-03-14 18:03:56520 let mut escape = false;
Michael Sullivan92743dc2012-07-14 05:57:48521 let mut res = ~"";
Erick Tryzelaar012dec52012-02-26 00:39:32522
523 while !self.eof() {
524 self.bump();
525
526 if (escape) {
Brian Andersonecaf9e32012-08-06 19:34:08527 match self.ch {
Erick Tryzelaar49d00b22012-09-24 16:55:42528 '"' => str::push_char(&res, '"'),
529 '\\' => str::push_char(&res, '\\'),
530 '/' => str::push_char(&res, '/'),
531 'b' => str::push_char(&res, '\x08'),
532 'f' => str::push_char(&res, '\x0c'),
533 'n' => str::push_char(&res, '\n'),
534 'r' => str::push_char(&res, '\r'),
535 't' => str::push_char(&res, '\t'),
Brian Anderson025d8662012-08-04 02:59:04536 'u' => {
Erick Tryzelaar012dec52012-02-26 00:39:32537 // Parse \u1234.
Niko Matsakis6b358752012-03-14 18:03:56538 let mut i = 0u;
539 let mut n = 0u;
Erick Tryzelaar012dec52012-02-26 00:39:32540 while i < 4u {
Brian Andersonecaf9e32012-08-06 19:34:08541 match self.next_char() {
Brian Anderson80c4f742012-09-02 01:38:05542 '0' .. '9' => {
Kevin Cantu4fb675b2012-08-31 03:12:10543 n = n * 16u + (self.ch as uint)
544 - ('0' as uint);
545 },
546 'a' | 'A' => n = n * 16u + 10u,
547 'b' | 'B' => n = n * 16u + 11u,
548 'c' | 'C' => n = n * 16u + 12u,
549 'd' | 'D' => n = n * 16u + 13u,
550 'e' | 'E' => n = n * 16u + 14u,
551 'f' | 'F' => n = n * 16u + 15u,
552 _ => return self.error(
553 ~"invalid \\u escape (unrecognized hex)")
Erick Tryzelaar012dec52012-02-26 00:39:32554 }
Niko Matsakis6b358752012-03-14 18:03:56555 i += 1u;
Erick Tryzelaar012dec52012-02-26 00:39:32556 }
557
558 // Error out if we didn't parse 4 digits.
559 if i != 4u {
Kevin Cantu4fb675b2012-08-31 03:12:10560 return self.error(
561 ~"invalid \\u escape (not four digits)");
Erick Tryzelaar012dec52012-02-26 00:39:32562 }
563
Erick Tryzelaar49d00b22012-09-24 16:55:42564 str::push_char(&res, n as char);
Erick Tryzelaar012dec52012-02-26 00:39:32565 }
Brian Anderson025d8662012-08-04 02:59:04566 _ => return self.error(~"invalid escape")
Erick Tryzelaar012dec52012-02-26 00:39:32567 }
568 escape = false;
569 } else if self.ch == '\\' {
570 escape = true;
571 } else {
572 if self.ch == '"' {
573 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42574 return Ok(res);
Erick Tryzelaar012dec52012-02-26 00:39:32575 }
Erick Tryzelaar49d00b22012-09-24 16:55:42576 str::push_char(&res, self.ch);
Erick Tryzelaar012dec52012-02-26 00:39:32577 }
578 }
579
Michael Sullivan92743dc2012-07-14 05:57:48580 self.error(~"EOF while parsing string")
Erick Tryzelaar012dec52012-02-26 00:39:32581 }
582
Ben Striegela605fd02012-08-11 14:08:42583 fn parse_list() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32584 self.bump();
585 self.parse_whitespace();
586
Michael Sullivan98e161f2012-06-29 23:26:56587 let mut values = ~[];
Erick Tryzelaar012dec52012-02-26 00:39:32588
589 if self.ch == ']' {
590 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42591 return Ok(List(values));
Erick Tryzelaar012dec52012-02-26 00:39:32592 }
593
Tim Chevalier35400e12012-03-11 04:34:17594 loop {
Erick Tryzelaar49d00b22012-09-24 16:55:42595 match move self.parse_value() {
Niko Matsakis67a8e712012-09-27 00:33:34596 Ok(move v) => values.push(v),
Erick Tryzelaar49d00b22012-09-24 16:55:42597 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32598 }
599
600 self.parse_whitespace();
Tim Chevalier35400e12012-03-11 04:34:17601 if self.eof() {
Brian Andersonb3559362012-08-02 00:30:05602 return self.error(~"EOF while parsing list");
Tim Chevalier35400e12012-03-11 04:34:17603 }
Erick Tryzelaar012dec52012-02-26 00:39:32604
Brian Andersonecaf9e32012-08-06 19:34:08605 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04606 ',' => self.bump(),
Erick Tryzelaar49d00b22012-09-24 16:55:42607 ']' => { self.bump(); return Ok(List(values)); }
Brian Anderson025d8662012-08-04 02:59:04608 _ => return self.error(~"expected `,` or `]`")
Erick Tryzelaar012dec52012-02-26 00:39:32609 }
Tim Chevalier35400e12012-03-11 04:34:17610 };
Erick Tryzelaar012dec52012-02-26 00:39:32611 }
612
Ben Striegela605fd02012-08-11 14:08:42613 fn parse_object() -> Result<Json, Error> {
Erick Tryzelaar012dec52012-02-26 00:39:32614 self.bump();
615 self.parse_whitespace();
616
Erick Tryzelaar49d00b22012-09-24 16:55:42617 let mut values = ~linear::LinearMap();
Erick Tryzelaar012dec52012-02-26 00:39:32618
619 if self.ch == '}' {
620 self.bump();
Erick Tryzelaar49d00b22012-09-24 16:55:42621 return Ok(Object(values));
Erick Tryzelaar012dec52012-02-26 00:39:32622 }
623
624 while !self.eof() {
625 self.parse_whitespace();
626
627 if self.ch != '"' {
Brian Andersonb3559362012-08-02 00:30:05628 return self.error(~"key must be a string");
Erick Tryzelaar012dec52012-02-26 00:39:32629 }
630
Erick Tryzelaar49d00b22012-09-24 16:55:42631 let key = match move self.parse_str() {
632 Ok(move key) => key,
633 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32634 };
635
636 self.parse_whitespace();
637
638 if self.ch != ':' {
639 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05640 return self.error(~"expected `:`");
Erick Tryzelaar012dec52012-02-26 00:39:32641 }
642 self.bump();
643
Erick Tryzelaar49d00b22012-09-24 16:55:42644 match move self.parse_value() {
645 Ok(move value) => { values.insert(key, value); }
646 Err(move e) => return Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32647 }
648 self.parse_whitespace();
649
Brian Andersonecaf9e32012-08-06 19:34:08650 match self.ch {
Brian Anderson025d8662012-08-04 02:59:04651 ',' => self.bump(),
Erick Tryzelaar49d00b22012-09-24 16:55:42652 '}' => { self.bump(); return Ok(Object(values)); }
Brian Anderson025d8662012-08-04 02:59:04653 _ => {
Erick Tryzelaar012dec52012-02-26 00:39:32654 if self.eof() { break; }
Brian Andersonb3559362012-08-02 00:30:05655 return self.error(~"expected `,` or `}`");
Erick Tryzelaar012dec52012-02-26 00:39:32656 }
657 }
658 }
659
Brian Andersonb3559362012-08-02 00:30:05660 return self.error(~"EOF while parsing object");
Elly Jonesbd726262011-11-07 19:01:28661 }
662}
663
Gareth Daniel Smithbe014162012-07-04 21:53:12664/// Deserializes a json value from an io::reader
Erick Tryzelaar49d00b22012-09-24 16:55:42665pub fn from_reader(rdr: io::Reader) -> Result<Json, Error> {
666 Parser(rdr).parse()
Elly Jonesbd726262011-11-07 19:01:28667}
668
Gareth Daniel Smithbe014162012-07-04 21:53:12669/// Deserializes a json value from a string
Erick Tryzelaar49d00b22012-09-24 16:55:42670pub fn from_str(s: &str) -> Result<Json, Error> {
671 do io::with_str_reader(s) |rdr| {
672 from_reader(rdr)
673 }
Erick Tryzelaar012dec52012-02-26 00:39:32674}
675
Erick Tryzelaar49d00b22012-09-24 16:55:42676pub struct Deserializer {
677 priv json: Json,
678 priv mut stack: ~[&Json],
679}
680
681pub fn Deserializer(rdr: io::Reader) -> Result<Deserializer, Error> {
682 match move from_reader(rdr) {
683 Ok(move json) => {
684 let des = Deserializer { json: json, stack: ~[] };
685 Ok(move des)
686 }
687 Err(move e) => Err(e)
Erick Tryzelaar012dec52012-02-26 00:39:32688 }
Elly Jonesbd726262011-11-07 19:01:28689}
Brian Anderson6e27b272012-01-18 03:05:07690
Erick Tryzelaar49d00b22012-09-24 16:55:42691priv impl Deserializer {
Niko Matsakis67a8e712012-09-27 00:33:34692 fn peek(&self) -> &self/Json {
693 if self.stack.len() == 0 { self.stack.push(&self.json); }
Erick Tryzelaar49d00b22012-09-24 16:55:42694 vec::last(self.stack)
695 }
696
Niko Matsakis67a8e712012-09-27 00:33:34697 fn pop(&self) -> &self/Json {
698 if self.stack.len() == 0 { self.stack.push(&self.json); }
Niko Matsakis21519bc2012-09-28 05:20:47699 self.stack.pop()
Erick Tryzelaar49d00b22012-09-24 16:55:42700 }
701}
702
703pub impl Deserializer: serialization2::Deserializer {
704 fn read_nil(&self) -> () {
705 debug!("read_nil");
706 match *self.pop() {
707 Null => (),
708 _ => fail ~"not a null"
709 }
710 }
711
712 fn read_u64(&self) -> u64 { self.read_float() as u64 }
713 fn read_u32(&self) -> u32 { self.read_float() as u32 }
714 fn read_u16(&self) -> u16 { self.read_float() as u16 }
715 fn read_u8 (&self) -> u8 { self.read_float() as u8 }
716 fn read_uint(&self) -> uint { self.read_float() as uint }
717
718 fn read_i64(&self) -> i64 { self.read_float() as i64 }
719 fn read_i32(&self) -> i32 { self.read_float() as i32 }
720 fn read_i16(&self) -> i16 { self.read_float() as i16 }
721 fn read_i8 (&self) -> i8 { self.read_float() as i8 }
722 fn read_int(&self) -> int { self.read_float() as int }
723
724 fn read_bool(&self) -> bool {
725 debug!("read_bool");
726 match *self.pop() {
727 Boolean(b) => b,
728 _ => fail ~"not a boolean"
729 }
730 }
731
732 fn read_f64(&self) -> f64 { self.read_float() as f64 }
733 fn read_f32(&self) -> f32 { self.read_float() as f32 }
734 fn read_float(&self) -> float {
735 debug!("read_float");
736 match *self.pop() {
737 Number(f) => f,
738 _ => fail ~"not a number"
739 }
740 }
741
742 fn read_str(&self) -> ~str {
743 debug!("read_str");
744 match *self.pop() {
745 String(ref s) => copy *s,
746 _ => fail ~"not a string"
747 }
748 }
749
750 fn read_enum<T>(&self, name: ~str, f: fn() -> T) -> T {
751 debug!("read_enum(%s)", name);
752 if name != ~"option" { fail ~"only supports the option enum" }
753 f()
754 }
755
756 fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T {
757 debug!("read_enum_variant()");
758 let idx = match *self.peek() {
759 Null => 0,
760 _ => 1,
761 };
762 f(idx)
763 }
764
765 fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T {
766 debug!("read_enum_variant_arg(idx=%u)", idx);
767 if idx != 0 { fail ~"unknown index" }
768 f()
769 }
770
771 fn read_vec<T>(&self, f: fn(uint) -> T) -> T {
772 debug!("read_vec()");
773 let len = match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34774 List(ref list) => list.len(),
Erick Tryzelaar49d00b22012-09-24 16:55:42775 _ => fail ~"not a list",
776 };
777 let res = f(len);
778 self.pop();
779 res
780 }
781
782 fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
783 debug!("read_vec_elt(idx=%u)", idx);
784 match *self.peek() {
785 List(ref list) => {
Niko Matsakis67a8e712012-09-27 00:33:34786 // FIXME(#3148)---should be inferred
787 let list: &self/~[Json] = list;
788
789 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42790 f()
791 }
792 _ => fail ~"not a list",
793 }
794 }
795
796 fn read_box<T>(&self, f: fn() -> T) -> T {
797 debug!("read_box()");
798 f()
799 }
800
801 fn read_uniq<T>(&self, f: fn() -> T) -> T {
802 debug!("read_uniq()");
803 f()
804 }
805
806 fn read_rec<T>(&self, f: fn() -> T) -> T {
807 debug!("read_rec()");
808 let value = f();
809 self.pop();
810 value
811 }
812
813 fn read_rec_field<T>(&self, f_name: ~str, f_idx: uint,
814 f: fn() -> T) -> T {
815 debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
816 let top = self.peek();
817 match *top {
818 Object(ref obj) => {
819 // FIXME(#3148) This hint should not be necessary.
820 let obj: &self/~Object = obj;
821
822 match obj.find_ref(&f_name) {
823 None => fail fmt!("no such field: %s", f_name),
824 Some(json) => {
Niko Matsakis67a8e712012-09-27 00:33:34825 self.stack.push(json);
Erick Tryzelaar49d00b22012-09-24 16:55:42826 f()
827 }
828 }
829 }
830 Number(_) => fail ~"num",
831 String(_) => fail ~"str",
832 Boolean(_) => fail ~"bool",
833 List(_) => fail fmt!("list: %?", top),
834 Null => fail ~"null",
835
836 //_ => fail fmt!("not an object: %?", *top)
837 }
838 }
839
840 fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T {
841 debug!("read_tup(sz=%u)", sz);
842 let value = f();
843 self.pop();
844 value
845 }
846
847 fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T {
848 debug!("read_tup_elt(idx=%u)", idx);
849 match *self.peek() {
Niko Matsakis67a8e712012-09-27 00:33:34850 List(ref list) => {
851 // FIXME(#3148)---should be inferred
852 let list: &self/~[Json] = list;
853 self.stack.push(&list[idx]);
Erick Tryzelaar49d00b22012-09-24 16:55:42854 f()
855 }
856 _ => fail ~"not a list"
857 }
858 }
859}
860
861impl Json : Eq {
862 pure fn eq(other: &Json) -> bool {
863 // XXX: This is ugly because matching on references is broken, and
864 // we can't match on dereferenced tuples without a copy.
865 match self {
866 Number(f0) =>
867 match *other { Number(f1) => f0 == f1, _ => false },
Brian Andersonbc9efaa2012-09-28 07:22:18868 String(ref s0) =>
869 match *other { String(ref s1) => s0 == s1, _ => false },
Erick Tryzelaar49d00b22012-09-24 16:55:42870 Boolean(b0) =>
871 match *other { Boolean(b1) => b0 == b1, _ => false },
872 Null =>
873 match *other { Null => true, _ => false },
874 List(v0) =>
875 match *other { List(v1) => v0 == v1, _ => false },
876 Object(ref d0) => {
877 match *other {
878 Object(ref d1) => {
879 if d0.len() == d1.len() {
880 let mut equal = true;
881 for d0.each |k, v0| {
882 match d1.find_ref(k) {
883 Some(v1) if v0 == v1 => { },
884 _ => { equal = false; break }
885 }
886 };
887 equal
888 } else {
889 false
890 }
891 }
892 _ => false
893 }
894 }
895 }
896 }
897 pure fn ne(other: &Json) -> bool { !self.eq(other) }
898}
899
Patrick Walton22b87572012-09-08 01:53:14900/// Test if two json values are less than one another
Erick Tryzelaar49d00b22012-09-24 16:55:42901impl Json : Ord {
902 pure fn lt(other: &Json) -> bool {
903 match self {
904 Number(f0) => {
905 match *other {
906 Number(f1) => f0 < f1,
907 String(_) | Boolean(_) | List(_) | Object(_) |
908 Null => true
909 }
Patrick Walton22b87572012-09-08 01:53:14910 }
Patrick Walton22b87572012-09-08 01:53:14911
Brian Andersonbc9efaa2012-09-28 07:22:18912 String(ref s0) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42913 match *other {
914 Number(_) => false,
Brian Andersonbc9efaa2012-09-28 07:22:18915 String(ref s1) => s0 < s1,
Erick Tryzelaar49d00b22012-09-24 16:55:42916 Boolean(_) | List(_) | Object(_) | Null => true
917 }
Patrick Walton22b87572012-09-08 01:53:14918 }
Patrick Walton22b87572012-09-08 01:53:14919
Erick Tryzelaar49d00b22012-09-24 16:55:42920 Boolean(b0) => {
921 match *other {
922 Number(_) | String(_) => false,
923 Boolean(b1) => b0 < b1,
924 List(_) | Object(_) | Null => true
925 }
Patrick Walton22b87572012-09-08 01:53:14926 }
Patrick Walton22b87572012-09-08 01:53:14927
Erick Tryzelaar49d00b22012-09-24 16:55:42928 List(l0) => {
929 match *other {
930 Number(_) | String(_) | Boolean(_) => false,
931 List(l1) => l0 < l1,
932 Object(_) | Null => true
933 }
Patrick Walton22b87572012-09-08 01:53:14934 }
Patrick Walton22b87572012-09-08 01:53:14935
Brian Andersonbc9efaa2012-09-28 07:22:18936 Object(ref d0) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42937 match *other {
938 Number(_) | String(_) | Boolean(_) | List(_) => false,
Brian Andersonbc9efaa2012-09-28 07:22:18939 Object(ref d1) => {
Erick Tryzelaar49d00b22012-09-24 16:55:42940 unsafe {
941 let mut d0_flat = ~[];
942 let mut d1_flat = ~[];
943
944 // XXX: this is horribly inefficient...
945 for d0.each |k, v| {
Niko Matsakis67a8e712012-09-27 00:33:34946 d0_flat.push((@copy *k, @copy *v));
Erick Tryzelaar49d00b22012-09-24 16:55:42947 }
Patrick Walton22b87572012-09-08 01:53:14948 d0_flat.qsort();
949
Erick Tryzelaar49d00b22012-09-24 16:55:42950 for d1.each |k, v| {
Niko Matsakis67a8e712012-09-27 00:33:34951 d1_flat.push((@copy *k, @copy *v));
Erick Tryzelaar49d00b22012-09-24 16:55:42952 }
Patrick Walton22b87572012-09-08 01:53:14953 d1_flat.qsort();
954
Erick Tryzelaar49d00b22012-09-24 16:55:42955 d0_flat < d1_flat
956 }
Patrick Walton22b87572012-09-08 01:53:14957 }
Erick Tryzelaar49d00b22012-09-24 16:55:42958 Null => true
Patrick Walton22b87572012-09-08 01:53:14959 }
Patrick Walton22b87572012-09-08 01:53:14960 }
Patrick Walton22b87572012-09-08 01:53:14961
Erick Tryzelaar49d00b22012-09-24 16:55:42962 Null => {
963 match *other {
964 Number(_) | String(_) | Boolean(_) | List(_) |
965 Object(_) =>
966 false,
967 Null => true
968 }
Patrick Walton22b87572012-09-08 01:53:14969 }
970 }
971 }
Erick Tryzelaar49d00b22012-09-24 16:55:42972 pure fn le(other: &Json) -> bool { !(*other).lt(&self) }
973 pure fn ge(other: &Json) -> bool { !self.lt(other) }
974 pure fn gt(other: &Json) -> bool { (*other).lt(&self) }
Patrick Walton22b87572012-09-08 01:53:14975}
976
Patrick Walton9117dcb2012-09-20 01:00:26977impl Error : Eq {
978 pure fn eq(other: &Error) -> bool {
Erick Tryzelaar49d00b22012-09-24 16:55:42979 self.line == other.line &&
980 self.col == other.col &&
981 self.msg == other.msg
Patrick Walton9117dcb2012-09-20 01:00:26982 }
983 pure fn ne(other: &Error) -> bool { !self.eq(other) }
984}
Patrick Walton96534362012-08-27 23:26:35985
Ben Striegela605fd02012-08-11 14:08:42986trait ToJson { fn to_json() -> Json; }
Erick Tryzelaared5af702012-05-28 19:10:32987
Ben Striegela605fd02012-08-11 14:08:42988impl Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:42989 fn to_json() -> Json { copy self }
Erick Tryzelaared5af702012-05-28 19:10:32990}
991
Ben Striegela605fd02012-08-11 14:08:42992impl @Json: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:42993 fn to_json() -> Json { (*self).to_json() }
Erick Tryzelaar11a56c32012-06-13 15:30:54994}
995
Ben Striegela605fd02012-08-11 14:08:42996impl int: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:42997 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:54998}
999
Ben Striegela605fd02012-08-11 14:08:421000impl i8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421001 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321002}
1003
Ben Striegela605fd02012-08-11 14:08:421004impl i16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421005 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321006}
1007
Ben Striegela605fd02012-08-11 14:08:421008impl i32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421009 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321010}
1011
Ben Striegela605fd02012-08-11 14:08:421012impl i64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421013 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321014}
1015
Ben Striegela605fd02012-08-11 14:08:421016impl uint: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421017 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaar11a56c32012-06-13 15:30:541018}
1019
Ben Striegela605fd02012-08-11 14:08:421020impl u8: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421021 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321022}
1023
Ben Striegela605fd02012-08-11 14:08:421024impl u16: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421025 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321026}
1027
Ben Striegela605fd02012-08-11 14:08:421028impl u32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421029 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321030}
1031
Ben Striegela605fd02012-08-11 14:08:421032impl u64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421033 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321034}
1035
Ben Striegela605fd02012-08-11 14:08:421036impl float: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421037 fn to_json() -> Json { Number(self) }
Erick Tryzelaared5af702012-05-28 19:10:321038}
1039
Ben Striegela605fd02012-08-11 14:08:421040impl f32: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421041 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321042}
1043
Ben Striegela605fd02012-08-11 14:08:421044impl f64: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421045 fn to_json() -> Json { Number(self as float) }
Erick Tryzelaared5af702012-05-28 19:10:321046}
1047
Ben Striegela605fd02012-08-11 14:08:421048impl (): ToJson {
1049 fn to_json() -> Json { Null }
Erick Tryzelaared5af702012-05-28 19:10:321050}
1051
Ben Striegela605fd02012-08-11 14:08:421052impl bool: ToJson {
1053 fn to_json() -> Json { Boolean(self) }
Erick Tryzelaared5af702012-05-28 19:10:321054}
1055
Ben Striegela605fd02012-08-11 14:08:421056impl ~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421057 fn to_json() -> Json { String(copy self) }
Erick Tryzelaarb361f6c2012-06-13 00:20:511058}
1059
Ben Striegela605fd02012-08-11 14:08:421060impl @~str: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421061 fn to_json() -> Json { String(copy *self) }
Erick Tryzelaared5af702012-05-28 19:10:321062}
1063
Ben Striegela605fd02012-08-11 14:08:421064impl <A: ToJson, B: ToJson> (A, B): ToJson {
1065 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081066 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181067 (ref a, ref b) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421068 List(~[a.to_json(), b.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561069 }
1070 }
Erick Tryzelaared5af702012-05-28 19:10:321071 }
1072}
1073
Ben Striegela605fd02012-08-11 14:08:421074impl <A: ToJson, B: ToJson, C: ToJson> (A, B, C): ToJson {
Ben Striegela605fd02012-08-11 14:08:421075 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081076 match self {
Brian Andersonbc9efaa2012-09-28 07:22:181077 (ref a, ref b, ref c) => {
Erick Tryzelaar49d00b22012-09-24 16:55:421078 List(~[a.to_json(), b.to_json(), c.to_json()])
Niko Matsakis97452c02012-08-02 22:42:561079 }
1080 }
Erick Tryzelaared5af702012-05-28 19:10:321081 }
1082}
1083
Ben Striegela605fd02012-08-11 14:08:421084impl <A: ToJson> ~[A]: ToJson {
Erick Tryzelaar49d00b22012-09-24 16:55:421085 fn to_json() -> Json { List(self.map(|elt| elt.to_json())) }
Erick Tryzelaared5af702012-05-28 19:10:321086}
1087
Erick Tryzelaar49d00b22012-09-24 16:55:421088impl <A: ToJson Copy> linear::LinearMap<~str, A>: ToJson {
Ben Striegela605fd02012-08-11 14:08:421089 fn to_json() -> Json {
Erick Tryzelaar49d00b22012-09-24 16:55:421090 let mut d = linear::LinearMap();
Brian Andersond1fc2b52012-06-30 23:19:071091 for self.each() |key, value| {
Erick Tryzelaar49d00b22012-09-24 16:55:421092 d.insert(copy *key, value.to_json());
Erick Tryzelaared5af702012-05-28 19:10:321093 }
Erick Tryzelaar49d00b22012-09-24 16:55:421094 Object(~d)
Erick Tryzelaared5af702012-05-28 19:10:321095 }
1096}
1097
Erick Tryzelaar49d00b22012-09-24 16:55:421098/*
1099impl <A: ToJson Copy> @std::map::HashMap<~str, A>: ToJson {
1100 fn to_json() -> Json {
1101 let mut d = linear::LinearMap();
1102 for self.each_ref |key, value| {
1103 d.insert(copy *key, value.to_json());
1104 }
1105 Object(~d)
1106 }
1107}
1108*/
1109
Ben Striegela605fd02012-08-11 14:08:421110impl <A: ToJson> Option<A>: ToJson {
1111 fn to_json() -> Json {
Brian Andersonecaf9e32012-08-06 19:34:081112 match self {
Ben Striegela605fd02012-08-11 14:08:421113 None => Null,
Brian Andersonbc9efaa2012-09-28 07:22:181114 Some(ref value) => value.to_json()
Erick Tryzelaared5af702012-05-28 19:10:321115 }
1116 }
1117}
1118
Ben Striegela605fd02012-08-11 14:08:421119impl Json: to_str::ToStr {
Erick Tryzelaar49d00b22012-09-24 16:55:421120 fn to_str() -> ~str { to_str(&self) }
Erick Tryzelaared5af702012-05-28 19:10:321121}
1122
Ben Striegela605fd02012-08-11 14:08:421123impl Error: to_str::ToStr {
Michael Sullivan92743dc2012-07-14 05:57:481124 fn to_str() -> ~str {
Paul Stansifer29f32b42012-08-23 00:24:521125 fmt!("%u:%u: %s", self.line, self.col, *self.msg)
Erick Tryzelaara8161762012-06-11 15:32:381126 }
1127}
1128
Brian Anderson6e27b272012-01-18 03:05:071129#[cfg(test)]
1130mod tests {
Erick Tryzelaar49d00b22012-09-24 16:55:421131 fn mk_object(items: &[(~str, Json)]) -> Json {
1132 let mut d = ~linear::LinearMap();
Erick Tryzelaar012dec52012-02-26 00:39:321133
Erick Tryzelaar49d00b22012-09-24 16:55:421134 for items.each |item| {
1135 match *item {
Brian Andersona09a4962012-09-28 09:26:201136 (copy key, copy value) => { d.insert(key, value); },
Erick Tryzelaar49d00b22012-09-24 16:55:421137 }
Erick Tryzelaar012dec52012-02-26 00:39:321138 };
1139
Erick Tryzelaar49d00b22012-09-24 16:55:421140 Object(d)
Brian Anderson6e27b272012-01-18 03:05:071141 }
1142
1143 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321144 fn test_write_null() {
Erick Tryzelaar49d00b22012-09-24 16:55:421145 assert to_str(&Null) == ~"null";
Brian Anderson6e27b272012-01-18 03:05:071146 }
1147
1148 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421149 fn test_write_number() {
1150 assert to_str(&Number(3f)) == ~"3";
1151 assert to_str(&Number(3.1f)) == ~"3.1";
1152 assert to_str(&Number(-1.5f)) == ~"-1.5";
1153 assert to_str(&Number(0.5f)) == ~"0.5";
Brian Anderson6e27b272012-01-18 03:05:071154 }
1155
1156 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321157 fn test_write_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421158 assert to_str(&String(~"")) == ~"\"\"";
1159 assert to_str(&String(~"foo")) == ~"\"foo\"";
Brian Anderson6e27b272012-01-18 03:05:071160 }
1161
1162 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321163 fn test_write_bool() {
Erick Tryzelaar49d00b22012-09-24 16:55:421164 assert to_str(&Boolean(true)) == ~"true";
1165 assert to_str(&Boolean(false)) == ~"false";
Brian Anderson6e27b272012-01-18 03:05:071166 }
1167
1168 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321169 fn test_write_list() {
Erick Tryzelaar49d00b22012-09-24 16:55:421170 assert to_str(&List(~[])) == ~"[]";
1171 assert to_str(&List(~[Boolean(true)])) == ~"[true]";
1172 assert to_str(&List(~[
Ben Striegela605fd02012-08-11 14:08:421173 Boolean(false),
1174 Null,
Erick Tryzelaar49d00b22012-09-24 16:55:421175 List(~[String(~"foo\nbar"), Number(3.5f)])
1176 ])) == ~"[false,null,[\"foo\\nbar\",3.5]]";
Erick Tryzelaar012dec52012-02-26 00:39:321177 }
1178
1179 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421180 fn test_write_object() {
1181 assert to_str(&mk_object(~[])) == ~"{}";
1182 assert to_str(&mk_object(~[(~"a", Boolean(true))]))
1183 == ~"{\"a\":true}";
1184 let a = mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421185 (~"a", Boolean(true)),
Erick Tryzelaar49d00b22012-09-24 16:55:421186 (~"b", List(~[
1187 mk_object(~[(~"c", String(~"\x0c\r"))]),
1188 mk_object(~[(~"d", String(~""))])
Michael Sullivan98e161f2012-06-29 23:26:561189 ]))
Graydon Hoare11871b82012-08-30 23:27:151190 ]);
Erick Tryzelaar49d00b22012-09-24 16:55:421191 // We can't compare the strings directly because the object fields be
1192 // printed in a different order.
1193 let b = result::unwrap(from_str(to_str(&a)));
Graydon Hoare11871b82012-08-30 23:27:151194 assert a == b;
Erick Tryzelaar012dec52012-02-26 00:39:321195 }
1196
1197 #[test]
1198 fn test_trailing_characters() {
Michael Sullivan92743dc2012-07-14 05:57:481199 assert from_str(~"nulla") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421200 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481201 assert from_str(~"truea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421202 Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481203 assert from_str(~"falsea") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421204 Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481205 assert from_str(~"1a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421206 Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481207 assert from_str(~"[]a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421208 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Michael Sullivan92743dc2012-07-14 05:57:481209 assert from_str(~"{}a") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421210 Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"});
Erick Tryzelaar012dec52012-02-26 00:39:321211 }
1212
1213 #[test]
1214 fn test_read_identifiers() {
Michael Sullivan92743dc2012-07-14 05:57:481215 assert from_str(~"n") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421216 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481217 assert from_str(~"nul") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421218 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321219
Michael Sullivan92743dc2012-07-14 05:57:481220 assert from_str(~"t") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421221 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481222 assert from_str(~"truz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421223 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321224
Michael Sullivan92743dc2012-07-14 05:57:481225 assert from_str(~"f") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421226 Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481227 assert from_str(~"faz") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421228 Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321229
Ben Striegela605fd02012-08-11 14:08:421230 assert from_str(~"null") == Ok(Null);
1231 assert from_str(~"true") == Ok(Boolean(true));
1232 assert from_str(~"false") == Ok(Boolean(false));
1233 assert from_str(~" null ") == Ok(Null);
1234 assert from_str(~" true ") == Ok(Boolean(true));
1235 assert from_str(~" false ") == Ok(Boolean(false));
Erick Tryzelaar012dec52012-02-26 00:39:321236 }
1237
1238 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421239 fn test_read_number() {
Michael Sullivan92743dc2012-07-14 05:57:481240 assert from_str(~"+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421241 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481242 assert from_str(~".") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421243 Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"});
Erick Tryzelaar012dec52012-02-26 00:39:321244
Michael Sullivan92743dc2012-07-14 05:57:481245 assert from_str(~"-") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421246 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481247 assert from_str(~"00") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421248 Err(Error {line: 1u, col: 2u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481249 assert from_str(~"1.") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421250 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481251 assert from_str(~"1e") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421252 Err(Error {line: 1u, col: 3u, msg: @~"invalid number"});
Michael Sullivan92743dc2012-07-14 05:57:481253 assert from_str(~"1e+") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421254 Err(Error {line: 1u, col: 4u, msg: @~"invalid number"});
Erick Tryzelaar012dec52012-02-26 00:39:321255
Erick Tryzelaar49d00b22012-09-24 16:55:421256 assert from_str(~"3") == Ok(Number(3f));
1257 assert from_str(~"3.1") == Ok(Number(3.1f));
1258 assert from_str(~"-1.2") == Ok(Number(-1.2f));
1259 assert from_str(~"0.4") == Ok(Number(0.4f));
1260 assert from_str(~"0.4e5") == Ok(Number(0.4e5f));
1261 assert from_str(~"0.4e+15") == Ok(Number(0.4e15f));
1262 assert from_str(~"0.4e-01") == Ok(Number(0.4e-01f));
1263 assert from_str(~" 3 ") == Ok(Number(3f));
Erick Tryzelaar012dec52012-02-26 00:39:321264 }
1265
1266 #[test]
1267 fn test_read_str() {
Michael Sullivan92743dc2012-07-14 05:57:481268 assert from_str(~"\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421269 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"});
Michael Sullivan92743dc2012-07-14 05:57:481270 assert from_str(~"\"lol") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421271 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"});
Erick Tryzelaar012dec52012-02-26 00:39:321272
Erick Tryzelaar49d00b22012-09-24 16:55:421273 assert from_str(~"\"\"") == Ok(String(~""));
1274 assert from_str(~"\"foo\"") == Ok(String(~"foo"));
1275 assert from_str(~"\"\\\"\"") == Ok(String(~"\""));
1276 assert from_str(~"\"\\b\"") == Ok(String(~"\x08"));
1277 assert from_str(~"\"\\n\"") == Ok(String(~"\n"));
1278 assert from_str(~"\"\\r\"") == Ok(String(~"\r"));
1279 assert from_str(~"\"\\t\"") == Ok(String(~"\t"));
1280 assert from_str(~" \"foo\" ") == Ok(String(~"foo"));
Erick Tryzelaar012dec52012-02-26 00:39:321281 }
1282
1283 #[test]
Kevin Cantucf386182012-08-31 04:03:191284 fn test_unicode_hex_escapes_in_str() {
Erick Tryzelaar49d00b22012-09-24 16:55:421285 assert from_str(~"\"\\u12ab\"") == Ok(String(~"\u12ab"));
1286 assert from_str(~"\"\\uAB12\"") == Ok(String(~"\uAB12"));
Kevin Cantucf386182012-08-31 04:03:191287 }
1288
1289 #[test]
Erick Tryzelaar012dec52012-02-26 00:39:321290 fn test_read_list() {
Michael Sullivan92743dc2012-07-14 05:57:481291 assert from_str(~"[") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421292 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481293 assert from_str(~"[1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421294 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"});
Michael Sullivan92743dc2012-07-14 05:57:481295 assert from_str(~"[1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421296 Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481297 assert from_str(~"[1,]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421298 Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"});
Michael Sullivan92743dc2012-07-14 05:57:481299 assert from_str(~"[6 7]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421300 Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"});
Erick Tryzelaar012dec52012-02-26 00:39:321301
Erick Tryzelaar49d00b22012-09-24 16:55:421302 assert from_str(~"[]") == Ok(List(~[]));
1303 assert from_str(~"[ ]") == Ok(List(~[]));
1304 assert from_str(~"[true]") == Ok(List(~[Boolean(true)]));
1305 assert from_str(~"[ false ]") == Ok(List(~[Boolean(false)]));
1306 assert from_str(~"[null]") == Ok(List(~[Null]));
1307 assert from_str(~"[3, 1]") == Ok(List(~[Number(3f), Number(1f)]));
1308 assert from_str(~"\n[3, 2]\n") == Ok(List(~[Number(3f), Number(2f)]));
Michael Sullivan92743dc2012-07-14 05:57:481309 assert from_str(~"[2, [4, 1]]") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421310 Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])]));
Erick Tryzelaar012dec52012-02-26 00:39:321311 }
1312
1313 #[test]
Erick Tryzelaar49d00b22012-09-24 16:55:421314 fn test_read_object() {
Michael Sullivan92743dc2012-07-14 05:57:481315 assert from_str(~"{") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421316 Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481317 assert from_str(~"{ ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421318 Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481319 assert from_str(~"{1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421320 Err(Error {line: 1u, col: 2u, msg: @~"key must be a string"});
Michael Sullivan92743dc2012-07-14 05:57:481321 assert from_str(~"{ \"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421322 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481323 assert from_str(~"{\"a\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421324 Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481325 assert from_str(~"{\"a\" ") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421326 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321327
Michael Sullivan92743dc2012-07-14 05:57:481328 assert from_str(~"{\"a\" 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421329 Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"});
Michael Sullivan92743dc2012-07-14 05:57:481330 assert from_str(~"{\"a\":") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421331 Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"});
Michael Sullivan92743dc2012-07-14 05:57:481332 assert from_str(~"{\"a\":1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421333 Err(Error {line: 1u, col: 7u, msg: @~"EOF while parsing object"});
Michael Sullivan92743dc2012-07-14 05:57:481334 assert from_str(~"{\"a\":1 1") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421335 Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"});
Michael Sullivan92743dc2012-07-14 05:57:481336 assert from_str(~"{\"a\":1,") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421337 Err(Error {line: 1u, col: 8u, msg: @~"EOF while parsing object"});
Erick Tryzelaar012dec52012-02-26 00:39:321338
Erick Tryzelaar49d00b22012-09-24 16:55:421339 assert result::unwrap(from_str(~"{}")) == mk_object(~[]);
1340 assert result::unwrap(from_str(~"{\"a\": 3}")) ==
1341 mk_object(~[(~"a", Number(3.0f))]);
Erick Tryzelaar012dec52012-02-26 00:39:321342
Erick Tryzelaar49d00b22012-09-24 16:55:421343 assert result::unwrap(from_str(~"{ \"a\": null, \"b\" : true }")) ==
1344 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421345 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421346 (~"b", Boolean(true))]);
1347 assert result::unwrap(
1348 from_str(~"\n{ \"a\": null, \"b\" : true }\n")) ==
1349 mk_object(~[
Ben Striegela605fd02012-08-11 14:08:421350 (~"a", Null),
Erick Tryzelaar49d00b22012-09-24 16:55:421351 (~"b", Boolean(true))]);
1352 assert result::unwrap(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")) ==
1353 mk_object(~[
1354 (~"a", Number(1.0)),
1355 (~"b", List(~[Boolean(true)]))
1356 ]);
1357 assert result::unwrap(from_str(
Michael Sullivan92743dc2012-07-14 05:57:481358 ~"{" +
1359 ~"\"a\": 1.0, " +
1360 ~"\"b\": [" +
1361 ~"true," +
1362 ~"\"foo\\nbar\", " +
1363 ~"{ \"c\": {\"d\": null} } " +
1364 ~"]" +
Erick Tryzelaar49d00b22012-09-24 16:55:421365 ~"}")) ==
1366 mk_object(~[
1367 (~"a", Number(1.0f)),
1368 (~"b", List(~[
Ben Striegela605fd02012-08-11 14:08:421369 Boolean(true),
Erick Tryzelaar49d00b22012-09-24 16:55:421370 String(~"foo\nbar"),
1371 mk_object(~[
1372 (~"c", mk_object(~[(~"d", Null)]))
Michael Sullivan98e161f2012-06-29 23:26:561373 ])
1374 ]))
Erick Tryzelaar49d00b22012-09-24 16:55:421375 ]);
Erick Tryzelaar012dec52012-02-26 00:39:321376 }
1377
1378 #[test]
1379 fn test_multiline_errors() {
Michael Sullivan92743dc2012-07-14 05:57:481380 assert from_str(~"{\n \"foo\":\n \"bar\"") ==
Erick Tryzelaar49d00b22012-09-24 16:55:421381 Err(Error {line: 3u, col: 8u, msg: @~"EOF while parsing object"});
Brian Anderson6e27b272012-01-18 03:05:071382 }
1383}