diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index f77d36d1e0648..4927a8293a4da 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -105,7 +105,8 @@ pub enum EbmlEncoderTag { pub enum Error { IntTooBig(uint), Expected(String), - IoError(std::io::IoError) + IoError(std::io::IoError), + ApplicationError(String) } // -------------------------------------- @@ -119,11 +120,11 @@ pub mod reader { use serialize; - use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey, - EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8, - EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint, - EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, Error, IntTooBig, - Expected }; + use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, + EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, + EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, + EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, + Error, IntTooBig, Expected }; pub type DecodeResult = Result; // rbml reading @@ -636,6 +637,10 @@ pub mod reader { debug!("read_map_elt_val(idx={})", idx); self.push_doc(EsMapVal, f) } + + fn error(&mut self, err: &str) -> Error { + ApplicationError(err.to_string()) + } } } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 0752c68f4d0b2..58d69e38cc6e0 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -257,6 +257,7 @@ pub enum DecoderError { ExpectedError(String, String), MissingFieldError(String), UnknownVariantError(String), + ApplicationError(String) } /// Returns a readable error string for a given error code. @@ -2071,6 +2072,10 @@ impl ::Decoder for Decoder { debug!("read_map_elt_val(idx={})", idx); f(self) } + + fn error(&mut self, err: &str) -> DecoderError { + ApplicationError(err.to_string()) + } } /// A trait for converting values to JSON diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 03d9445b9b94b..95c677bcbd727 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -163,6 +163,9 @@ pub trait Decoder { fn read_map(&mut self, f: |&mut Self, uint| -> Result) -> Result; fn read_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> Result) -> Result; fn read_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> Result) -> Result; + + // Failure + fn error(&mut self, err: &str) -> E; } pub trait Encodable, E> { diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs index 2ffed792abd46..d922dde6f8537 100644 --- a/src/libuuid/lib.rs +++ b/src/libuuid/lib.rs @@ -501,7 +501,10 @@ impl, E> Encodable for Uuid { impl, E> Decodable for Uuid { /// Decode a UUID from a string fn decode(d: &mut T) -> Result { - Ok(from_str(try!(d.read_str()).as_slice()).unwrap()) + match from_str(try!(d.read_str()).as_slice()) { + Some(decode) => Ok(decode), + None => Err(d.error("Unable to decode UUID")) + } } } @@ -802,6 +805,23 @@ mod test { assert_eq!(u, u2); } + #[test] + fn test_bad_decode() { + use serialize::json; + use serialize::{Encodable, Decodable}; + + let js_good = json::String("a1a2a3a4a5a6a7a8a1a2a3a4a5a6a7a8".to_string()); + let js_bad1 = json::String("a1a2a3a4a5a6a7a8a1a2a3a4a5a6a7ah".to_string()); + let js_bad2 = json::String("a1a2a3a4a5a6a7a8a1a2a3a4a5a6a7a".to_string()); + + let u_good: Result = Decodable::decode(&mut json::Decoder::new(js_good)); + let u_bad1: Result = Decodable::decode(&mut json::Decoder::new(js_bad1)); + let u_bad2: Result = Decodable::decode(&mut json::Decoder::new(js_bad2)); + assert!(u_good.is_ok()); + assert!(u_bad1.is_err()); + assert!(u_bad2.is_err()); + } + #[test] fn test_iterbytes_impl_for_uuid() { use std::collections::HashSet;