about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Poelstra <apoelstra@wpsoftware.net>2014-07-30 19:35:32 -0700
committerAndrew Poelstra <apoelstra@wpsoftware.net>2014-07-31 21:41:19 -0700
commit5bd8edc1121a5736994d69b2dc9cf3efb6fbc116 (patch)
tree6f465585ab0d0ef8bc4555f912d280df2e5245b1
parentb495933a7fdc5e7b28ddbb058d1e2dab330ace7b (diff)
downloadrust-5bd8edc1121a5736994d69b2dc9cf3efb6fbc116.tar.gz
rust-5bd8edc1121a5736994d69b2dc9cf3efb6fbc116.zip
libserialize: add `error()` to `Decoder`
A quick and dirty fix for #15036 until we get serious decoder reform.

Right now it is impossible for a Decodable to signal a decode error,
for example if it has only finitely many allowed values, is a string
which must be encoded a certain way, needs a valid checksum, etc. For
example in the libuuid implementation of Decodable an Option is
unwrapped, meaning that a decode of a malformed UUID will cause the
task to fail.

Since this adds a method to the `Decoder` trait, all users will need
to update their implementations to add it. The strategy used for the
current implementations for JSON and EBML is to add a new entry to
the error enum `ApplicationError(String)` which stores the string
provided to `.error()`.

[breaking-change]
-rw-r--r--src/librbml/lib.rs17
-rw-r--r--src/libserialize/json.rs5
-rw-r--r--src/libserialize/serialize.rs3
3 files changed, 19 insertions, 6 deletions
diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index f77d36d1e06..4927a8293a4 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<T> = Result<T, Error>;
     // 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 0752c68f4d0..58d69e38cc6 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<DecoderError> 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 03d9445b9b9..95c677bcbd7 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -163,6 +163,9 @@ pub trait Decoder<E> {
     fn read_map<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>;
     fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
     fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
+
+    // Failure
+    fn error(&mut self, err: &str) -> E;
 }
 
 pub trait Encodable<S:Encoder<E>, E> {