diff options
| author | Sean McArthur <sean.monstar@gmail.com> | 2014-03-18 10:58:26 -0700 |
|---|---|---|
| committer | Sean McArthur <sean.monstar@gmail.com> | 2014-03-27 17:41:55 -0700 |
| commit | f1739b14a1346419a4598339aee32aab07e0d12e (patch) | |
| tree | 1f22c1cc492f9729cd1420654f97f3b511938369 /src/libserialize/json.rs | |
| parent | 13dafa09f1a80b8b50f41cab42ac2bfd24dfa6b9 (diff) | |
| download | rust-f1739b14a1346419a4598339aee32aab07e0d12e.tar.gz rust-f1739b14a1346419a4598339aee32aab07e0d12e.zip | |
serialize: use Result
All of Decoder and Encoder's methods now return a Result. Encodable.encode() and Decodable.decode() return a Result as well. fixes #12292
Diffstat (limited to 'src/libserialize/json.rs')
| -rw-r--r-- | src/libserialize/json.rs | 860 |
1 files changed, 412 insertions, 448 deletions
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index c52cfb1e35d..f2bdef445bd 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -72,7 +72,10 @@ fn main() { let mut m = io::MemWriter::new(); { let mut encoder = json::Encoder::new(&mut m as &mut std::io::Writer); - to_encode_object.encode(&mut encoder); + match to_encode_object.encode(&mut encoder) { + Ok(()) => (), + Err(e) => fail!("json encoding error: {}", e) + }; } } ``` @@ -141,7 +144,10 @@ fn main() { ~"{\"attr1\":1,\"attr2\":\"toto\"}"; let json_object = json::from_str(json_str_to_decode); let mut decoder = json::Decoder::new(json_object.unwrap()); - let decoded_object: MyStruct = Decodable::decode(&mut decoder); // create the final object + let decoded_object: MyStruct = match Decodable::decode(&mut decoder) { + Ok(v) => v, + Err(e) => fail!("Decoding error: {}", e) + }; // create the final object } ``` @@ -174,7 +180,7 @@ fn main() { let json_object = json::from_str(encoded_str); let mut decoder = json::Decoder::new(json_object.unwrap()); - let decoded1: TestStruct1 = Decodable::decode(&mut decoder); // create the final object + let decoded1: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); // create the final object } ``` @@ -219,7 +225,7 @@ fn main() { let mut decoder = json::Decoder::new(json::from_str(json_str).unwrap()); // create the final object - let decoded2: TestStruct1 = Decodable::decode(&mut decoder); + let decoded2: TestStruct1 = Decodable::decode(&mut decoder).unwrap(); } ``` @@ -237,10 +243,6 @@ use std::fmt; use Encodable; use collections::TreeMap; -macro_rules! try( ($e:expr) => ( - match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } } -) ) - /// Represents a json value #[deriving(Clone, Eq)] pub enum Json { @@ -255,25 +257,18 @@ pub enum Json { pub type List = ~[Json]; pub type Object = TreeMap<~str, Json>; -#[deriving(Eq)] -/// If an error occurs while parsing some JSON, this is the structure which is -/// returned -pub struct Error { - /// The line number at which the error occurred - priv line: uint, - /// The column number at which the error occurred - priv col: uint, - /// A message describing the type of the error - priv msg: ~str, +#[deriving(Eq, Show)] +pub enum Error { + /// msg, line, col + ParseError(~str, uint, uint), + ExpectedError(~str, ~str), + MissingFieldError(~str), + UnknownVariantError(~str), + IoError(io::IoError) } -fn io_error_to_error(io: io::IoError) -> Error { - Error { - line: 0, - col: 0, - msg: format!("io error: {}", io) - } -} +pub type EncodeResult = io::IoResult<()>; +pub type DecodeResult<T> = Result<T, Error>; fn escape_str(s: &str) -> ~str { let mut escaped = ~"\""; @@ -304,183 +299,203 @@ fn spaces(n: uint) -> ~str { /// A structure for implementing serialization to JSON. pub struct Encoder<'a> { priv wr: &'a mut io::Writer, - priv error: io::IoResult<()>, } impl<'a> Encoder<'a> { /// Creates a new JSON encoder whose output will be written to the writer /// specified. pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> { - Encoder { wr: wr, error: Ok(()) } + Encoder { wr: wr } } /// Encode the specified struct into a json [u8] - pub fn buffer_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~[u8] { + pub fn buffer_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T) -> ~[u8] { //Serialize the object in a string using a writer let mut m = MemWriter::new(); { let mut encoder = Encoder::new(&mut m as &mut io::Writer); - to_encode_object.encode(&mut encoder); + // MemWriter never Errs + let _ = to_encode_object.encode(&mut encoder); } m.unwrap() } /// Encode the specified struct into a json str - pub fn str_encode<T:Encodable<Encoder<'a>>>(to_encode_object: &T) -> ~str { + pub fn str_encode<T:Encodable<Encoder<'a>, io::IoError>>(to_encode_object: &T) -> ~str { let buff:~[u8] = Encoder::buffer_encode(to_encode_object); str::from_utf8_owned(buff).unwrap() } } -impl<'a> ::Encoder for Encoder<'a> { - fn emit_nil(&mut self) { try!(write!(self.wr, "null")) } +impl<'a> ::Encoder<io::IoError> for Encoder<'a> { + fn emit_nil(&mut self) -> EncodeResult { write!(self.wr, "null") } - fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } - fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } - fn emit_u32(&mut self, v: u32) { self.emit_f64(v as f64); } - fn emit_u16(&mut self, v: u16) { self.emit_f64(v as f64); } - fn emit_u8(&mut self, v: u8) { self.emit_f64(v as f64); } + fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_int(&mut self, v: int) { self.emit_f64(v as f64); } - fn emit_i64(&mut self, v: i64) { self.emit_f64(v as f64); } - fn emit_i32(&mut self, v: i32) { self.emit_f64(v as f64); } - fn emit_i16(&mut self, v: i16) { self.emit_f64(v as f64); } - fn emit_i8(&mut self, v: i8) { self.emit_f64(v as f64); } + fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_bool(&mut self, v: bool) { + fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { - try!(write!(self.wr, "true")); + write!(self.wr, "true") } else { - try!(write!(self.wr, "false")); + write!(self.wr, "false") } } - fn emit_f64(&mut self, v: f64) { - try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u))) + fn emit_f64(&mut self, v: f64) -> EncodeResult { + write!(self.wr, "{}", f64::to_str_digits(v, 6u)) } - fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } + fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) } - fn emit_str(&mut self, v: &str) { - try!(write!(self.wr, "{}", escape_str(v))) + fn emit_char(&mut self, v: char) -> EncodeResult { self.emit_str(str::from_char(v)) } + fn emit_str(&mut self, v: &str) -> EncodeResult { + write!(self.wr, "{}", escape_str(v)) } - fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) } + fn emit_enum(&mut self, + _name: &str, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { f(self) } fn emit_enum_variant(&mut self, name: &str, _id: uint, cnt: uint, - f: |&mut Encoder<'a>|) { + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { // enums are encoded as strings or objects // Bunny => "Bunny" // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} if cnt == 0 { - try!(write!(self.wr, "{}", escape_str(name))); + write!(self.wr, "{}", escape_str(name)) } else { try!(write!(self.wr, "\\{\"variant\":")); try!(write!(self.wr, "{}", escape_str(name))); try!(write!(self.wr, ",\"fields\":[")); - f(self); - try!(write!(self.wr, "]\\}")); + try!(f(self)); + write!(self.wr, "]\\}") } } - fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { + fn emit_enum_variant_arg(&mut self, + idx: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { if idx != 0 { try!(write!(self.wr, ",")); } - f(self); + f(self) } fn emit_enum_struct_variant(&mut self, name: &str, id: uint, cnt: uint, - f: |&mut Encoder<'a>|) { + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_enum_variant(name, id, cnt, f) } fn emit_enum_struct_variant_field(&mut self, _: &str, idx: uint, - f: |&mut Encoder<'a>|) { + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_enum_variant_arg(idx, f) } - fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) { + fn emit_struct(&mut self, + _: &str, + _: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { try!(write!(self.wr, r"\{")); - f(self); - try!(write!(self.wr, r"\}")); + try!(f(self)); + write!(self.wr, r"\}") } fn emit_struct_field(&mut self, name: &str, idx: uint, - f: |&mut Encoder<'a>|) { - if idx != 0 { try!(write!(self.wr, ",")) } + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + if idx != 0 { try!(write!(self.wr, ",")); } try!(write!(self.wr, "{}:", escape_str(name))); - f(self); + f(self) } - fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) { + fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq(len, f) } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { + fn emit_tuple_arg(&mut self, + idx: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq_elt(idx, f) } fn emit_tuple_struct(&mut self, _name: &str, len: uint, - f: |&mut Encoder<'a>|) { + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq(len, f) } - fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) { + fn emit_tuple_struct_arg(&mut self, + idx: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq_elt(idx, f) } - fn emit_option(&mut self, f: |&mut Encoder<'a>|) { f(self); } - fn emit_option_none(&mut self) { self.emit_nil(); } - fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); } + fn emit_option(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + f(self) + } + fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } + fn emit_option_some(&mut self, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { + f(self) + } - fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) { + fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { try!(write!(self.wr, "[")); - f(self); - try!(write!(self.wr, "]")); + try!(f(self)); + write!(self.wr, "]") } - fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) { + fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { if idx != 0 { try!(write!(self.wr, ",")); } f(self) } - fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) { + fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { try!(write!(self.wr, r"\{")); - f(self); - try!(write!(self.wr, r"\}")); + try!(f(self)); + write!(self.wr, r"\}") } - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) { + fn emit_map_elt_key(&mut self, + idx: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { use std::str::from_utf8; if idx != 0 { try!(write!(self.wr, ",")) } // ref #12967, make sure to wrap a key in double quotes, // in the event that its of a type that omits them (eg numbers) let mut buf = MemWriter::new(); let mut check_encoder = Encoder::new(&mut buf); - f(&mut check_encoder); + try!(f(&mut check_encoder)); let buf = buf.unwrap(); let out = from_utf8(buf).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.wr, "\"")); } - f(self); + try!(f(self)); if needs_wrapping { try!(write!(self.wr, "\"")); } + Ok(()) } - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) { + fn emit_map_elt_val(&mut self, + _idx: uint, + f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult { try!(write!(self.wr, ":")); f(self) } @@ -491,7 +506,6 @@ impl<'a> ::Encoder for Encoder<'a> { pub struct PrettyEncoder<'a> { priv wr: &'a mut io::Writer, priv indent: uint, - priv error: io::IoResult<()>, } impl<'a> PrettyEncoder<'a> { @@ -500,45 +514,46 @@ impl<'a> PrettyEncoder<'a> { PrettyEncoder { wr: wr, indent: 0, - error: Ok(()) } } } -impl<'a> ::Encoder for PrettyEncoder<'a> { - fn emit_nil(&mut self) { try!(write!(self.wr, "null")); } +impl<'a> ::Encoder<io::IoError> for PrettyEncoder<'a> { + fn emit_nil(&mut self) -> EncodeResult { write!(self.wr, "null") } - fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); } - fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); } - fn emit_u32(&mut self, v: u32) { self.emit_f64(v as f64); } - fn emit_u16(&mut self, v: u16) { self.emit_f64(v as f64); } - fn emit_u8(&mut self, v: u8) { self.emit_f64(v as f64); } + fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_int(&mut self, v: int) { self.emit_f64(v as f64); } - fn emit_i64(&mut self, v: i64) { self.emit_f64(v as f64); } - fn emit_i32(&mut self, v: i32) { self.emit_f64(v as f64); } - fn emit_i16(&mut self, v: i16) { self.emit_f64(v as f64); } - fn emit_i8(&mut self, v: i8) { self.emit_f64(v as f64); } + fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_bool(&mut self, v: bool) { + fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { - try!(write!(self.wr, "true")); + write!(self.wr, "true") } else { - try!(write!(self.wr, "false")); + write!(self.wr, "false") } } - fn emit_f64(&mut self, v: f64) { - try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u))); + fn emit_f64(&mut self, v: f64) -> EncodeResult { + write!(self.wr, "{}", f64::to_str_digits(v, 6u)) } - fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); } + fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) } - fn emit_str(&mut self, v: &str) { - try!(write!(self.wr, "{}", escape_str(v))); + fn emit_char(&mut self, v: char) -> EncodeResult { self.emit_str(str::from_char(v)) } + fn emit_str(&mut self, v: &str) -> EncodeResult { + write!(self.wr, "{}", escape_str(v)) } - fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) { + fn emit_enum(&mut self, + _name: &str, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { f(self) } @@ -546,22 +561,22 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { name: &str, _: uint, cnt: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if cnt == 0 { - try!(write!(self.wr, "{}", escape_str(name))); + write!(self.wr, "{}", escape_str(name)) } else { self.indent += 2; try!(write!(self.wr, "[\n{}{},\n", spaces(self.indent), escape_str(name))); - f(self); + try!(f(self)); self.indent -= 2; - try!(write!(self.wr, "\n{}]", spaces(self.indent))); + write!(self.wr, "\n{}]", spaces(self.indent)) } } fn emit_enum_variant_arg(&mut self, idx: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if idx != 0 { try!(write!(self.wr, ",\n")); } @@ -573,14 +588,14 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { name: &str, id: uint, cnt: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_enum_variant(name, id, cnt, f) } fn emit_enum_struct_variant_field(&mut self, _: &str, idx: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_enum_variant_arg(idx, f) } @@ -588,67 +603,79 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { fn emit_struct(&mut self, _: &str, len: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if len == 0 { - try!(write!(self.wr, "\\{\\}")); + write!(self.wr, "\\{\\}") } else { try!(write!(self.wr, "\\{")); self.indent += 2; - f(self); + try!(f(self)); self.indent -= 2; - try!(write!(self.wr, "\n{}\\}", spaces(self.indent))); + write!(self.wr, "\n{}\\}", spaces(self.indent)) } } fn emit_struct_field(&mut self, name: &str, idx: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if idx == 0 { try!(write!(self.wr, "\n")); } else { try!(write!(self.wr, ",\n")); } try!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name))); - f(self); + f(self) } - fn emit_tuple(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_tuple(&mut self, + len: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq(len, f) } - fn emit_tuple_arg(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_tuple_arg(&mut self, + idx: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq_elt(idx, f) } fn emit_tuple_struct(&mut self, _: &str, len: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq(len, f) } fn emit_tuple_struct_arg(&mut self, idx: uint, - f: |&mut PrettyEncoder<'a>|) { + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { self.emit_seq_elt(idx, f) } - fn emit_option(&mut self, f: |&mut PrettyEncoder<'a>|) { f(self); } - fn emit_option_none(&mut self) { self.emit_nil(); } - fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'a>|) { f(self); } + fn emit_option(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + f(self) + } + fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } + fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { + f(self) + } - fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_seq(&mut self, + len: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if len == 0 { - try!(write!(self.wr, "[]")); + write!(self.wr, "[]") } else { try!(write!(self.wr, "[")); self.indent += 2; - f(self); + try!(f(self)); self.indent -= 2; - try!(write!(self.wr, "\n{}]", spaces(self.indent))); + write!(self.wr, "\n{}]", spaces(self.indent)) } } - fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_seq_elt(&mut self, + idx: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if idx == 0 { try!(write!(self.wr, "\n")); } else { @@ -658,19 +685,23 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { f(self) } - fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_map(&mut self, + len: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { if len == 0 { - try!(write!(self.wr, "\\{\\}")); + write!(self.wr, "\\{\\}") } else { try!(write!(self.wr, "\\{")); self.indent += 2; - f(self); + try!(f(self)); self.indent -= 2; - try!(write!(self.wr, "\n{}\\}", spaces(self.indent))); + write!(self.wr, "\n{}\\}", spaces(self.indent)) } } - fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_map_elt_key(&mut self, + idx: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { use std::str::from_utf8; if idx == 0 { try!(write!(self.wr, "\n")); @@ -682,24 +713,27 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { // in the event that its of a type that omits them (eg numbers) let mut buf = MemWriter::new(); let mut check_encoder = PrettyEncoder::new(&mut buf); - f(&mut check_encoder); + try!(f(&mut check_encoder)); let buf = buf.unwrap(); let out = from_utf8(buf).unwrap(); let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; if needs_wrapping { try!(write!(self.wr, "\"")); } - f(self); + try!(f(self)); if needs_wrapping { try!(write!(self.wr, "\"")); } + Ok(()) } - fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) { + fn emit_map_elt_val(&mut self, + _idx: uint, + f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult { try!(write!(self.wr, ": ")); - f(self); + f(self) } } -impl<E: ::Encoder> Encodable<E> for Json { - fn encode(&self, e: &mut E) { +impl<E: ::Encoder<io::IoError>> Encodable<E, io::IoError> for Json { + fn encode(&self, e: &mut E) -> EncodeResult { match *self { Number(v) => v.encode(e), String(ref v) => v.encode(e), @@ -713,18 +747,16 @@ impl<E: ::Encoder> Encodable<E> for Json { impl Json { /// Encodes a json value into a io::writer. Uses a single line. - pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> { + pub fn to_writer(&self, wr: &mut io::Writer) -> EncodeResult { let mut encoder = Encoder::new(wr); - self.encode(&mut encoder); - encoder.error + self.encode(&mut encoder) } /// Encodes a json value into a io::writer. /// Pretty-prints in a more readable format. - pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> { + pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> EncodeResult { let mut encoder = PrettyEncoder::new(wr); - self.encode(&mut encoder); - encoder.error + self.encode(&mut encoder) } /// Encodes a json value into a string @@ -888,7 +920,7 @@ impl<T: Iterator<char>> Parser<T> { } impl<T: Iterator<char>> Parser<T> { - pub fn parse(&mut self) -> Result<Json, Error> { + pub fn parse(&mut self) -> DecodeResult<Json> { match self.parse_value() { Ok(value) => { // Skip trailing whitespaces. @@ -927,11 +959,11 @@ impl<T : Iterator<char>> Parser<T> { self.ch == Some(c) } - fn error<T>(&self, msg: ~str) -> Result<T, Error> { - Err(Error { line: self.line, col: self.col, msg: msg }) + fn error<T>(&self, msg: ~str) -> DecodeResult<T> { + Err(ParseError(msg, self.line, self.col)) } - fn parse_value(&mut self) -> Result<Json, Error> { + fn parse_value(&mut self) -> DecodeResult<Json> { self.parse_whitespace(); if self.eof() { return self.error(~"EOF while parsing value"); } @@ -960,7 +992,7 @@ impl<T : Iterator<char>> Parser<T> { self.ch_is('\r') { self.bump(); } } - fn parse_ident(&mut self, ident: &str, value: Json) -> Result<Json, Error> { + fn parse_ident(&mut self, ident: &str, value: Json) -> DecodeResult<Json> { if ident.chars().all(|c| Some(c) == self.next_char()) { self.bump(); Ok(value) @@ -969,7 +1001,7 @@ impl<T : Iterator<char>> Parser<T> { } } - fn parse_number(&mut self) -> Result<Json, Error> { + fn parse_number(&mut self) -> DecodeResult<Json> { let mut neg = 1.0; if self.ch_is('-') { @@ -999,7 +1031,7 @@ impl<T : Iterator<char>> Parser<T> { Ok(Number(neg * res)) } - fn parse_integer(&mut self) -> Result<f64, Error> { + fn parse_integer(&mut self) -> DecodeResult<f64> { let mut res = 0.0; match self.ch_or_null() { @@ -1030,7 +1062,7 @@ impl<T : Iterator<char>> Parser<T> { Ok(res) } - fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> { + fn parse_decimal(&mut self, res: f64) -> DecodeResult<f64> { self.bump(); // Make sure a digit follows the decimal place. @@ -1056,7 +1088,7 @@ impl<T : Iterator<char>> Parser<T> { Ok(res) } - fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> { + fn parse_exponent(&mut self, mut res: f64) -> DecodeResult<f64> { self.bump(); let mut exp = 0u; @@ -1096,7 +1128,7 @@ impl<T : Iterator<char>> Parser<T> { Ok(res) } - fn parse_str(&mut self) -> Result<~str, Error> { + fn parse_str(&mut self) -> DecodeResult<~str> { let mut escape = false; let mut res = ~""; @@ -1160,7 +1192,7 @@ impl<T : Iterator<char>> Parser<T> { } } - fn parse_list(&mut self) -> Result<Json, Error> { + fn parse_list(&mut self) -> DecodeResult<Json> { self.bump(); self.parse_whitespace(); @@ -1193,7 +1225,7 @@ impl<T : Iterator<char>> Parser<T> { }; } - fn parse_object(&mut self) -> Result<Json, Error> { + fn parse_object(&mut self) -> DecodeResult<Json> { self.bump(); self.parse_whitespace(); @@ -1245,21 +1277,21 @@ impl<T : Iterator<char>> Parser<T> { } /// Decodes a json value from an `&mut io::Reader` -pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> { +pub fn from_reader(rdr: &mut io::Reader) -> DecodeResult<Json> { let contents = match rdr.read_to_end() { Ok(c) => c, - Err(e) => return Err(io_error_to_error(e)) + Err(e) => return Err(IoError(e)) }; let s = match str::from_utf8_owned(contents) { Some(s) => s, - None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" }) + None => return Err(ParseError(~"contents not utf-8", 0, 0)) }; let mut parser = Parser::new(s.chars()); parser.parse() } /// Decodes a json value from a string -pub fn from_str(s: &str) -> Result<Json, Error> { +pub fn from_str(s: &str) -> DecodeResult<Json> { let mut parser = Parser::new(s.chars()); parser.parse() } @@ -1279,110 +1311,103 @@ impl Decoder { } impl Decoder { - fn err(&self, msg: &str) -> ! { - fail!("JSON decode error: {}", msg); - } - fn missing_field(&self, field: &str, object: ~Object) -> ! { - self.err(format!("missing required '{}' field in object: {}", - field, Object(object).to_str())) - } - fn expected(&self, expected: &str, found: &Json) -> ! { - let found_s = match *found { - Null => "null", - List(..) => "list", - Object(..) => "object", - Number(..) => "number", - String(..) => "string", - Boolean(..) => "boolean" - }; - self.err(format!("expected {expct} but found {fnd}: {val}", - expct=expected, fnd=found_s, val=found.to_str())) + fn pop(&mut self) -> Json { + self.stack.pop().unwrap() } } -impl ::Decoder for Decoder { - fn read_nil(&mut self) -> () { - debug!("read_nil"); - match self.stack.pop().unwrap() { - Null => (), - value => self.expected("null", &value) +macro_rules! expect( + ($e:expr, Null) => ({ + match $e { + Null => Ok(()), + other => Err(ExpectedError(~"Null", format!("{}", other))) + } + }); + ($e:expr, $t:ident) => ({ + match $e { + $t(v) => Ok(v), + other => Err(ExpectedError(stringify!($t).to_owned(), format!("{}", other))) } + }) +) + +impl ::Decoder<Error> for Decoder { + fn read_nil(&mut self) -> DecodeResult<()> { + debug!("read_nil"); + try!(expect!(self.pop(), Null)); + Ok(()) } - fn read_u64(&mut self) -> u64 { self.read_f64() as u64 } - fn read_u32(&mut self) -> u32 { self.read_f64() as u32 } - fn read_u16(&mut self) -> u16 { self.read_f64() as u16 } - fn read_u8 (&mut self) -> u8 { self.read_f64() as u8 } - fn read_uint(&mut self) -> uint { self.read_f64() as uint } + fn read_u64(&mut self) -> DecodeResult<u64 > { Ok(try!(self.read_f64()) as u64) } + fn read_u32(&mut self) -> DecodeResult<u32 > { Ok(try!(self.read_f64()) as u32) } + fn read_u16(&mut self) -> DecodeResult<u16 > { Ok(try!(self.read_f64()) as u16) } + fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(try!(self.read_f64()) as u8) } + fn read_uint(&mut self) -> DecodeResult<uint> { Ok(try!(self.read_f64()) as uint) } - fn read_i64(&mut self) -> i64 { self.read_f64() as i64 } - fn read_i32(&mut self) -> i32 { self.read_f64() as i32 } - fn read_i16(&mut self) -> i16 { self.read_f64() as i16 } - fn read_i8 (&mut self) -> i8 { self.read_f64() as i8 } - fn read_int(&mut self) -> int { self.read_f64() as int } + fn read_i64(&mut self) -> DecodeResult<i64> { Ok(try!(self.read_f64()) as i64) } + fn read_i32(&mut self) -> DecodeResult<i32> { Ok(try!(self.read_f64()) as i32) } + fn read_i16(&mut self) -> DecodeResult<i16> { Ok(try!(self.read_f64()) as i16) } + fn read_i8 (&mut self) -> DecodeResult<i8 > { Ok(try!(self.read_f64()) as i8) } + fn read_int(&mut self) -> DecodeResult<int> { Ok(try!(self.read_f64()) as int) } - fn read_bool(&mut self) -> bool { + fn read_bool(&mut self) -> DecodeResult<bool> { debug!("read_bool"); - match self.stack.pop().unwrap() { - Boolean(b) => b, - value => self.expected("boolean", &value) - } + Ok(try!(expect!(self.pop(), Boolean))) } - fn read_f64(&mut self) -> f64 { + fn read_f64(&mut self) -> DecodeResult<f64> { use std::from_str::FromStr; debug!("read_f64"); - match self.stack.pop().unwrap() { - Number(f) => f, + match self.pop() { + Number(f) => Ok(f), String(s) => { // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc) // is going to have a string here, as per JSON spec.. - FromStr::from_str(s).unwrap() + Ok(FromStr::from_str(s).unwrap()) }, - value => self.expected("number", &value) + value => Err(ExpectedError(~"Number", format!("{}", value))) } } - fn read_f32(&mut self) -> f32 { self.read_f64() as f32 } + fn read_f32(&mut self) -> DecodeResult<f32> { Ok(try!(self.read_f64()) as f32) } - fn read_char(&mut self) -> char { - let s = self.read_str(); + fn read_char(&mut self) -> DecodeResult<char> { + let s = try!(self.read_str()); { let mut it = s.chars(); match (it.next(), it.next()) { // exactly one character - (Some(c), None) => return c, + (Some(c), None) => return Ok(c), _ => () } } - self.expected("single character string", &String(s)) + Err(ExpectedError(~"single character string", format!("{}", s))) } - fn read_str(&mut self) -> ~str { + fn read_str(&mut self) -> DecodeResult<~str> { debug!("read_str"); - match self.stack.pop().unwrap() { - String(s) => s, - value => self.expected("string", &value) - } + Ok(try!(expect!(self.pop(), String))) } - fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder| -> T) -> T { + fn read_enum<T>(&mut self, + name: &str, + f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_enum({})", name); f(self) } fn read_enum_variant<T>(&mut self, names: &[&str], - f: |&mut Decoder, uint| -> T) - -> T { + f: |&mut Decoder, uint| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_enum_variant(names={:?})", names); - let name = match self.stack.pop().unwrap() { + let name = match self.pop() { String(s) => s, Object(mut o) => { let n = match o.pop(&~"variant") { Some(String(s)) => s, - Some(val) => self.expected("string", &val), - None => self.missing_field("variant", o) + Some(val) => return Err(ExpectedError(~"String", format!("{}", val))), + None => return Err(MissingFieldError(~"variant")) }; match o.pop(&~"fields") { Some(List(l)) => { @@ -1390,36 +1415,30 @@ impl ::Decoder for Decoder { self.stack.push(field.clone()); } }, - Some(val) => self.expected("list", &val), - None => { - // re-insert the variant field so we're - // printing the "whole" struct in the error - // message... ick. - o.insert(~"variant", String(n)); - self.missing_field("fields", o); - } + Some(val) => return Err(ExpectedError(~"List", format!("{}", val))), + None => return Err(MissingFieldError(~"fields")) } n } - json => self.expected("string or object", &json) + json => return Err(ExpectedError(~"String or Object", format!("{}", json))) }; let idx = match names.iter().position(|n| str::eq_slice(*n, name)) { Some(idx) => idx, - None => self.err(format!("unknown variant name: {}", name)) + None => return Err(UnknownVariantError(name)) }; f(self, idx) } - fn read_enum_variant_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { + fn read_enum_variant_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_enum_variant_arg(idx={})", idx); f(self) } fn read_enum_struct_variant<T>(&mut self, names: &[&str], - f: |&mut Decoder, uint| -> T) - -> T { + f: |&mut Decoder, uint| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_enum_struct_variant(names={:?})", names); self.read_enum_variant(names, f) } @@ -1428,8 +1447,8 @@ impl ::Decoder for Decoder { fn read_enum_struct_variant_field<T>(&mut self, name: &str, idx: uint, - f: |&mut Decoder| -> T) - -> T { + f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx); self.read_enum_variant_arg(idx, f) } @@ -1437,113 +1456,104 @@ impl ::Decoder for Decoder { fn read_struct<T>(&mut self, name: &str, len: uint, - f: |&mut Decoder| -> T) - -> T { + f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_struct(name={}, len={})", name, len); - let value = f(self); - self.stack.pop().unwrap(); - value + let value = try!(f(self)); + self.pop(); + Ok(value) } fn read_struct_field<T>(&mut self, name: &str, idx: uint, - f: |&mut Decoder| -> T) - -> T { + f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_struct_field(name={}, idx={})", name, idx); - match self.stack.pop().unwrap() { - Object(mut obj) => { - let value = match obj.pop(&name.to_owned()) { - None => self.missing_field(name, obj), - Some(json) => { - self.stack.push(json); - f(self) - } - }; - self.stack.push(Object(obj)); - value + let mut obj = try!(expect!(self.pop(), Object)); + + let value = match obj.pop(&name.to_owned()) { + None => return Err(MissingFieldError(name.to_owned())), + Some(json) => { + self.stack.push(json); + try!(f(self)) } - value => self.expected("object", &value) - } + }; + self.stack.push(Object(obj)); + Ok(value) } - fn read_tuple<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T { + fn read_tuple<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_tuple()"); self.read_seq(f) } - fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T { + fn read_tuple_arg<T>(&mut self, + idx: uint, + f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_tuple_arg(idx={})", idx); self.read_seq_elt(idx, f) } fn read_tuple_struct<T>(&mut self, name: &str, - f: |&mut Decoder, uint| -> T) - -> T { + f: |&mut Decoder, uint| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_tuple_struct(name={})", name); self.read_tuple(f) } fn read_tuple_struct_arg<T>(&mut self, idx: uint, - f: |&mut Decoder| -> T) - -> T { + f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_tuple_struct_arg(idx={})", idx); self.read_tuple_arg(idx, f) } - fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> T) -> T { - match self.stack.pop().unwrap() { + fn read_option<T>(&mut self, f: |&mut Decoder, bool| -> DecodeResult<T>) -> DecodeResult<T> { + match self.pop() { Null => f(self, false), value => { self.stack.push(value); f(self, true) } } } - fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T { + fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_seq()"); - let len = match self.stack.pop().unwrap() { - List(list) => { - let len = list.len(); - for v in list.move_rev_iter() { - self.stack.push(v); - } - len - } - value => self.expected("list", &value) - }; + let list = try!(expect!(self.pop(), List)); + let len = list.len(); + for v in list.move_rev_iter() { + self.stack.push(v); + } f(self, len) } - fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T { + fn read_seq_elt<T>(&mut self, + idx: uint, + f: |&mut Decoder| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_seq_elt(idx={})", idx); f(self) } - fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T { + fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> DecodeResult<T>) -> DecodeResult<T> { debug!("read_map()"); - let len = match self.stack.pop().unwrap() { - Object(obj) => { - let len = obj.len(); - for (key, value) in obj.move_iter() { - self.stack.push(value); - self.stack.push(String(key)); - } - len - } - value => self.expected("object", &value) - }; + let obj = try!(expect!(self.pop(), Object)); + let len = obj.len(); + for (key, value) in obj.move_iter() { + self.stack.push(value); + self.stack.push(String(key)); + } f(self, len) } - fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { + fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_map_elt_key(idx={})", idx); f(self) } - fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) - -> T { + fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder| -> DecodeResult<T>) + -> DecodeResult<T> { debug!("read_map_elt_val(idx={})", idx); f(self) } @@ -1735,17 +1745,12 @@ impl fmt::Show for Json { } } -impl fmt::Show for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, "{}:{}: {}", self.line, self.col, self.msg) - } -} - #[cfg(test)] mod tests { use {Encodable, Decodable}; use super::{Encoder, Decoder, Error, Boolean, Number, List, String, Null, - PrettyEncoder, Object, Json, from_str}; + PrettyEncoder, Object, Json, from_str, ParseError, ExpectedError, + MissingFieldError, UnknownVariantError, DecodeResult }; use std::io; use collections::TreeMap; @@ -1931,14 +1936,14 @@ mod tests { assert_eq!( with_str_writer(|wr| { let mut encoder = Encoder::new(wr); - animal.encode(&mut encoder); + animal.encode(&mut encoder).unwrap(); }), ~"\"Dog\"" ); assert_eq!( with_str_writer(|wr| { let mut encoder = PrettyEncoder::new(wr); - animal.encode(&mut encoder); + animal.encode(&mut encoder).unwrap(); }), ~"\"Dog\"" ); @@ -1947,14 +1952,14 @@ mod tests { assert_eq!( with_str_writer(|wr| { let mut encoder = Encoder::new(wr); - animal.encode(&mut encoder); + animal.encode(&mut encoder).unwrap(); }), ~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" ); assert_eq!( with_str_writer(|wr| { let mut encoder = PrettyEncoder::new(wr); - animal.encode(&mut encoder); + animal.encode(&mut encoder).unwrap(); }), ~"\ [\n \ @@ -1970,14 +1975,14 @@ mod tests { let value = Some(~"jodhpurs"); let s = with_str_writer(|wr| { let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); + value.encode(&mut encoder).unwrap(); }); assert_eq!(s, ~"\"jodhpurs\""); let value = Some(~"jodhpurs"); let s = with_str_writer(|wr| { let mut encoder = PrettyEncoder::new(wr); - value.encode(&mut encoder); + value.encode(&mut encoder).unwrap(); }); assert_eq!(s, ~"\"jodhpurs\""); } @@ -1987,13 +1992,13 @@ mod tests { let value: Option<~str> = None; let s = with_str_writer(|wr| { let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); + value.encode(&mut encoder).unwrap(); }); assert_eq!(s, ~"null"); let s = with_str_writer(|wr| { let mut encoder = Encoder::new(wr); - value.encode(&mut encoder); + value.encode(&mut encoder).unwrap(); }); assert_eq!(s, ~"null"); } @@ -2001,35 +2006,35 @@ mod tests { #[test] fn test_trailing_characters() { assert_eq!(from_str("nulla"), - Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 5u))); assert_eq!(from_str("truea"), - Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 5u))); assert_eq!(from_str("falsea"), - Err(Error {line: 1u, col: 6u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 6u))); assert_eq!(from_str("1a"), - Err(Error {line: 1u, col: 2u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 2u))); assert_eq!(from_str("[]a"), - Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 3u))); assert_eq!(from_str("{}a"), - Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"})); + Err(ParseError(~"trailing characters", 1u, 3u))); } #[test] fn test_read_identifiers() { assert_eq!(from_str("n"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 2u))); assert_eq!(from_str("nul"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 4u))); assert_eq!(from_str("t"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 2u))); assert_eq!(from_str("truz"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 4u))); assert_eq!(from_str("f"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 2u))); assert_eq!(from_str("faz"), - Err(Error {line: 1u, col: 3u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 3u))); assert_eq!(from_str("null"), Ok(Null)); assert_eq!(from_str("true"), Ok(Boolean(true))); @@ -2042,35 +2047,35 @@ mod tests { #[test] fn test_decode_identifiers() { let mut decoder = Decoder::new(from_str("null").unwrap()); - let v: () = Decodable::decode(&mut decoder); + let v: () = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ()); let mut decoder = Decoder::new(from_str("true").unwrap()); - let v: bool = Decodable::decode(&mut decoder); + let v: bool = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, true); let mut decoder = Decoder::new(from_str("false").unwrap()); - let v: bool = Decodable::decode(&mut decoder); + let v: bool = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, false); } #[test] fn test_read_number() { assert_eq!(from_str("+"), - Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 1u))); assert_eq!(from_str("."), - Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 1u))); assert_eq!(from_str("-"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid number"})); + Err(ParseError(~"invalid number", 1u, 2u))); assert_eq!(from_str("00"), - Err(Error {line: 1u, col: 2u, msg: ~"invalid number"})); + Err(ParseError(~"invalid number", 1u, 2u))); assert_eq!(from_str("1."), - Err(Error {line: 1u, col: 3u, msg: ~"invalid number"})); + Err(ParseError(~"invalid number", 1u, 3u))); assert_eq!(from_str("1e"), - Err(Error {line: 1u, col: 3u, msg: ~"invalid number"})); + Err(ParseError(~"invalid number", 1u, 3u))); assert_eq!(from_str("1e+"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid number"})); + Err(ParseError(~"invalid number", 1u, 4u))); assert_eq!(from_str("3"), Ok(Number(3.0))); assert_eq!(from_str("3.1"), Ok(Number(3.1))); @@ -2085,42 +2090,40 @@ mod tests { #[test] fn test_decode_numbers() { let mut decoder = Decoder::new(from_str("3").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 3.0); let mut decoder = Decoder::new(from_str("3.1").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 3.1); let mut decoder = Decoder::new(from_str("-1.2").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, -1.2); let mut decoder = Decoder::new(from_str("0.4").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 0.4); let mut decoder = Decoder::new(from_str("0.4e5").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 0.4e5); let mut decoder = Decoder::new(from_str("0.4e15").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 0.4e15); let mut decoder = Decoder::new(from_str("0.4e-01").unwrap()); - let v: f64 = Decodable::decode(&mut decoder); + let v: f64 = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, 0.4e-01); } #[test] fn test_read_str() { assert_eq!(from_str("\""), - Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing string" - })); + Err(ParseError(~"EOF while parsing string", 1u, 2u))); assert_eq!(from_str("\"lol"), - Err(Error {line: 1u, col: 5u, msg: ~"EOF while parsing string" - })); + Err(ParseError(~"EOF while parsing string", 1u, 5u))); assert_eq!(from_str("\"\""), Ok(String(~""))); assert_eq!(from_str("\"foo\""), Ok(String(~"foo"))); @@ -2137,54 +2140,54 @@ mod tests { #[test] fn test_decode_str() { let mut decoder = Decoder::new(from_str("\"\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~""); let mut decoder = Decoder::new(from_str("\"foo\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"foo"); let mut decoder = Decoder::new(from_str("\"\\\"\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\""); let mut decoder = Decoder::new(from_str("\"\\b\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\x08"); let mut decoder = Decoder::new(from_str("\"\\n\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\n"); let mut decoder = Decoder::new(from_str("\"\\r\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\r"); let mut decoder = Decoder::new(from_str("\"\\t\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\t"); let mut decoder = Decoder::new(from_str("\"\\u12ab\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\u12ab"); let mut decoder = Decoder::new(from_str("\"\\uAB12\"").unwrap()); - let v: ~str = Decodable::decode(&mut decoder); + let v: ~str = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~"\uAB12"); } #[test] fn test_read_list() { assert_eq!(from_str("["), - Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing value"})); + Err(ParseError(~"EOF while parsing value", 1u, 2u))); assert_eq!(from_str("[1"), - Err(Error {line: 1u, col: 3u, msg: ~"EOF while parsing list"})); + Err(ParseError(~"EOF while parsing list", 1u, 3u))); assert_eq!(from_str("[1,"), - Err(Error {line: 1u, col: 4u, msg: ~"EOF while parsing value"})); + Err(ParseError(~"EOF while parsing value", 1u, 4u))); assert_eq!(from_str("[1,]"), - Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"})); + Err(ParseError(~"invalid syntax", 1u, 4u))); assert_eq!(from_str("[6 7]"), - Err(Error {line: 1u, col: 4u, msg: ~"expected `,` or `]`"})); + Err(ParseError(~"expected `,` or `]`", 1u, 4u))); assert_eq!(from_str("[]"), Ok(List(~[]))); assert_eq!(from_str("[ ]"), Ok(List(~[]))); @@ -2202,79 +2205,55 @@ mod tests { #[test] fn test_decode_list() { let mut decoder = Decoder::new(from_str("[]").unwrap()); - let v: ~[()] = Decodable::decode(&mut decoder); + let v: ~[()] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[]); let mut decoder = Decoder::new(from_str("[null]").unwrap()); - let v: ~[()] = Decodable::decode(&mut decoder); + let v: ~[()] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[()]); let mut decoder = Decoder::new(from_str("[true]").unwrap()); - let v: ~[bool] = Decodable::decode(&mut decoder); + let v: ~[bool] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[true]); let mut decoder = Decoder::new(from_str("[true]").unwrap()); - let v: ~[bool] = Decodable::decode(&mut decoder); + let v: ~[bool] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[true]); let mut decoder = Decoder::new(from_str("[3, 1]").unwrap()); - let v: ~[int] = Decodable::decode(&mut decoder); + let v: ~[int] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[3, 1]); let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap()); - let v: ~[~[uint]] = Decodable::decode(&mut decoder); + let v: ~[~[uint]] = Decodable::decode(&mut decoder).unwrap(); assert_eq!(v, ~[~[3], ~[1, 2]]); } #[test] fn test_read_object() { assert_eq!(from_str("{"), - Err(Error { - line: 1u, - col: 2u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 2u))); assert_eq!(from_str("{ "), - Err(Error { - line: 1u, - col: 3u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 3u))); assert_eq!(from_str("{1"), - Err(Error { - line: 1u, - col: 2u, - msg: ~"key must be a string"})); + Err(ParseError(~"key must be a string", 1u, 2u))); assert_eq!(from_str("{ \"a\""), - Err(Error { - line: 1u, - col: 6u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 6u))); assert_eq!(from_str("{\"a\""), - Err(Error { - line: 1u, - col: 5u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 5u))); assert_eq!(from_str("{\"a\" "), - Err(Error { - line: 1u, - col: 6u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 6u))); assert_eq!(from_str("{\"a\" 1"), - Err(Error {line: 1u, col: 6u, msg: ~"expected `:`"})); + Err(ParseError(~"expected `:`", 1u, 6u))); assert_eq!(from_str("{\"a\":"), - Err(Error {line: 1u, col: 6u, msg: ~"EOF while parsing value"})); + Err(ParseError(~"EOF while parsing value", 1u, 6u))); assert_eq!(from_str("{\"a\":1"), - Err(Error { - line: 1u, - col: 7u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 7u))); assert_eq!(from_str("{\"a\":1 1"), - Err(Error {line: 1u, col: 8u, msg: ~"expected `,` or `}`"})); + Err(ParseError(~"expected `,` or `}`", 1u, 8u))); assert_eq!(from_str("{\"a\":1,"), - Err(Error { - line: 1u, - col: 8u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 1u, 8u))); assert_eq!(from_str("{}").unwrap(), mk_object([])); assert_eq!(from_str("{\"a\": 3}").unwrap(), @@ -2324,7 +2303,7 @@ mod tests { ] }"; let mut decoder = Decoder::new(from_str(s).unwrap()); - let v: Outer = Decodable::decode(&mut decoder); + let v: Outer = Decodable::decode(&mut decoder).unwrap(); assert_eq!( v, Outer { @@ -2338,23 +2317,23 @@ mod tests { #[test] fn test_decode_option() { let mut decoder = Decoder::new(from_str("null").unwrap()); - let value: Option<~str> = Decodable::decode(&mut decoder); + let value: Option<~str> = Decodable::decode(&mut decoder).unwrap(); assert_eq!(value, None); let mut decoder = Decoder::new(from_str("\"jodhpurs\"").unwrap()); - let value: Option<~str> = Decodable::decode(&mut decoder); + let value: Option<~str> = Decodable::decode(&mut decoder).unwrap(); assert_eq!(value, Some(~"jodhpurs")); } #[test] fn test_decode_enum() { let mut decoder = Decoder::new(from_str("\"Dog\"").unwrap()); - let value: Animal = Decodable::decode(&mut decoder); + let value: Animal = Decodable::decode(&mut decoder).unwrap(); assert_eq!(value, Dog); let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; let mut decoder = Decoder::new(from_str(s).unwrap()); - let value: Animal = Decodable::decode(&mut decoder); + let value: Animal = Decodable::decode(&mut decoder).unwrap(); assert_eq!(value, Frog(~"Henry", 349)); } @@ -2362,7 +2341,7 @@ mod tests { fn test_decode_map() { let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}"; let mut decoder = Decoder::new(from_str(s).unwrap()); - let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder); + let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder).unwrap(); assert_eq!(map.pop(&~"a"), Some(Dog)); assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349))); @@ -2371,10 +2350,7 @@ mod tests { #[test] fn test_multiline_errors() { assert_eq!(from_str("{\n \"foo\":\n \"bar\""), - Err(Error { - line: 3u, - col: 8u, - msg: ~"EOF while parsing object"})); + Err(ParseError(~"EOF while parsing object", 3u, 8u))); } #[deriving(Decodable)] @@ -2389,60 +2365,48 @@ mod tests { A(f64), B(~str) } - fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str) { - use std::any::AnyRefExt; - use std::task; - let res = task::try(proc() { - // either fails in `decode` (which is what we want), or - // returns Some(error_message)/None if the string was - // invalid or valid JSON. - match from_str(to_parse) { - Err(e) => Some(e.to_str()), - Ok(json) => { - let _: T = Decodable::decode(&mut Decoder::new(json)); - None - } - } - }); + fn check_err<T: Decodable<Decoder, Error>>(to_parse: &'static str, expected: Error) { + let res: DecodeResult<T> = match from_str(to_parse) { + Err(e) => Err(e), + Ok(json) => Decodable::decode(&mut Decoder::new(json)) + }; match res { - Ok(Some(parse_error)) => fail!("`{}` is not valid json: {}", - to_parse, parse_error), - Ok(None) => fail!("`{}` parsed & decoded ok, expecting error `{}`", - to_parse, expected_error), + Ok(_) => fail!("`{}` parsed & decoded ok, expecting error `{}`", + to_parse, expected), + Err(ParseError(e, _, _)) => fail!("`{}` is not valid json: {}", + to_parse, e), Err(e) => { - let err = e.as_ref::<~str>().unwrap(); - assert!(err.contains(expected_error), - "`{}` errored incorrectly, found `{}` expecting `{}`", - to_parse, *err, expected_error); + assert_eq!(e, expected); } + } } #[test] fn test_decode_errors_struct() { - check_err::<DecodeStruct>("[]", "object but found list"); + check_err::<DecodeStruct>("[]", ExpectedError(~"Object", ~"[]")); check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - "number but found boolean"); + ExpectedError(~"Number", ~"true")); check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - "boolean but found list"); + ExpectedError(~"Boolean", ~"[]")); check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - "string but found object"); + ExpectedError(~"String", ~"{}")); check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - "list but found null"); + ExpectedError(~"List", ~"null")); check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}", - "'w' field in object"); + MissingFieldError(~"w")); } #[test] fn test_decode_errors_enum() { check_err::<DecodeEnum>("{}", - "'variant' field in object"); + MissingFieldError(~"variant")); check_err::<DecodeEnum>("{\"variant\": 1}", - "string but found number"); + ExpectedError(~"String", ~"1")); check_err::<DecodeEnum>("{\"variant\": \"A\"}", - "'fields' field in object"); + MissingFieldError(~"fields")); check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}", - "list but found null"); + ExpectedError(~"List", ~"null")); check_err::<DecodeEnum>("{\"variant\": \"C\", \"fields\": []}", - "unknown variant name"); + UnknownVariantError(~"C")); } #[test] @@ -2561,7 +2525,7 @@ mod tests { let mut mem_buf = MemWriter::new(); { let mut encoder = Encoder::new(&mut mem_buf as &mut io::Writer); - hm.encode(&mut encoder) + hm.encode(&mut encoder).unwrap(); } let bytes = mem_buf.unwrap(); let json_str = from_utf8(bytes).unwrap(); @@ -2581,7 +2545,7 @@ mod tests { let mut mem_buf = MemWriter::new(); { let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut io::Writer); - hm.encode(&mut encoder) + hm.encode(&mut encoder).unwrap(); } let bytes = mem_buf.unwrap(); let json_str = from_utf8(bytes).unwrap(); @@ -2600,6 +2564,6 @@ mod tests { Ok(o) => o }; let mut decoder = Decoder::new(json_obj); - let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder); + let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder).unwrap(); } } |
