about summary refs log tree commit diff
path: root/src/libserialize
diff options
context:
space:
mode:
authorSean McArthur <sean.monstar@gmail.com>2014-03-18 10:58:26 -0700
committerSean McArthur <sean.monstar@gmail.com>2014-03-27 17:41:55 -0700
commitf1739b14a1346419a4598339aee32aab07e0d12e (patch)
tree1f22c1cc492f9729cd1420654f97f3b511938369 /src/libserialize
parent13dafa09f1a80b8b50f41cab42ac2bfd24dfa6b9 (diff)
downloadrust-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')
-rw-r--r--src/libserialize/collection_impls.rs242
-rw-r--r--src/libserialize/collection_impls_old.rs292
-rw-r--r--src/libserialize/ebml.rs633
-rw-r--r--src/libserialize/ebml_old.rs1120
-rw-r--r--src/libserialize/json.rs860
-rw-r--r--src/libserialize/json_old.rs2606
-rw-r--r--src/libserialize/lib.rs21
-rw-r--r--src/libserialize/serialize.rs473
-rw-r--r--src/libserialize/serialize_old.rs688
9 files changed, 5867 insertions, 1068 deletions
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index bb823c2d8ca..8631fef5168 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -20,272 +20,294 @@ use collections::{DList, RingBuf, TreeMap, TreeSet, Deque, HashMap, HashSet,
 use collections::enum_set::{EnumSet, CLike};
 
 impl<
-    S: Encoder,
-    T: Encodable<S>
-> Encodable<S> for DList<T> {
-    fn encode(&self, s: &mut S) {
+    E,
+    S: Encoder<E>,
+    T: Encodable<S, E>
+> Encodable<S, E> for DList<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
-                s.emit_seq_elt(i, |s| e.encode(s));
+                try!(s.emit_seq_elt(i, |s| e.encode(s)));
             }
+            Ok(())
         })
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> {
-    fn decode(d: &mut D) -> DList<T> {
-        let mut list = DList::new();
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for DList<T> {
+    fn decode(d: &mut D) -> Result<DList<T>, E> {
         d.read_seq(|d, len| {
+            let mut list = DList::new();
             for i in range(0u, len) {
-                list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-        });
-        list
+            Ok(list)
+        })
     }
 }
 
 impl<
-    S: Encoder,
-    T: Encodable<S>
-> Encodable<S> for RingBuf<T> {
-    fn encode(&self, s: &mut S) {
+    E,
+    S: Encoder<E>,
+    T: Encodable<S, E>
+> Encodable<S, E> for RingBuf<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
-                s.emit_seq_elt(i, |s| e.encode(s));
+                try!(s.emit_seq_elt(i, |s| e.encode(s)));
             }
+            Ok(())
         })
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> {
-    fn decode(d: &mut D) -> RingBuf<T> {
-        let mut deque = RingBuf::new();
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for RingBuf<T> {
+    fn decode(d: &mut D) -> Result<RingBuf<T>, E> {
         d.read_seq(|d, len| {
+            let mut deque: RingBuf<T> = RingBuf::new();
             for i in range(0u, len) {
-                deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-        });
-        deque
+            Ok(deque)
+        })
     }
 }
 
 impl<
-    E: Encoder,
-    K: Encodable<E> + Eq + TotalOrd,
-    V: Encodable<E> + Eq
-> Encodable<E> for TreeMap<K, V> {
-    fn encode(&self, e: &mut E) {
+    E,
+    S: Encoder<E>,
+    K: Encodable<S, E> + Eq + TotalOrd,
+    V: Encodable<S, E> + Eq
+> Encodable<S, E> for TreeMap<K, V> {
+    fn encode(&self, e: &mut S) -> Result<(), E> {
         e.emit_map(self.len(), |e| {
             let mut i = 0;
             for (key, val) in self.iter() {
-                e.emit_map_elt_key(i, |e| key.encode(e));
-                e.emit_map_elt_val(i, |e| val.encode(e));
+                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
+                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                 i += 1;
             }
+            Ok(())
         })
     }
 }
 
 impl<
-    D: Decoder,
-    K: Decodable<D> + Eq + TotalOrd,
-    V: Decodable<D> + Eq
-> Decodable<D> for TreeMap<K, V> {
-    fn decode(d: &mut D) -> TreeMap<K, V> {
+    E,
+    D: Decoder<E>,
+    K: Decodable<D, E> + Eq + TotalOrd,
+    V: Decodable<D, E> + Eq
+> Decodable<D, E> for TreeMap<K, V> {
+    fn decode(d: &mut D) -> Result<TreeMap<K, V>, E> {
         d.read_map(|d, len| {
             let mut map = TreeMap::new();
             for i in range(0u, len) {
-                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
-                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
+                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                 map.insert(key, val);
             }
-            map
+            Ok(map)
         })
     }
 }
 
 impl<
-    S: Encoder,
-    T: Encodable<S> + Eq + TotalOrd
-> Encodable<S> for TreeSet<T> {
-    fn encode(&self, s: &mut S) {
+    E,
+    S: Encoder<E>,
+    T: Encodable<S, E> + Eq + TotalOrd
+> Encodable<S, E> for TreeSet<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             let mut i = 0;
             for e in self.iter() {
-                s.emit_seq_elt(i, |s| e.encode(s));
+                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                 i += 1;
             }
+            Ok(())
         })
     }
 }
 
 impl<
-    D: Decoder,
-    T: Decodable<D> + Eq + TotalOrd
-> Decodable<D> for TreeSet<T> {
-    fn decode(d: &mut D) -> TreeSet<T> {
+    E,
+    D: Decoder<E>,
+    T: Decodable<D, E> + Eq + TotalOrd
+> Decodable<D, E> for TreeSet<T> {
+    fn decode(d: &mut D) -> Result<TreeSet<T>, E> {
         d.read_seq(|d, len| {
             let mut set = TreeSet::new();
             for i in range(0u, len) {
-                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-            set
+            Ok(set)
         })
     }
 }
 
 impl<
-    S: Encoder,
-    T: Encodable<S> + CLike
-> Encodable<S> for EnumSet<T> {
-    fn encode(&self, s: &mut S) {
+    E,
+    S: Encoder<E>,
+    T: Encodable<S, E> + CLike
+> Encodable<S, E> for EnumSet<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         let mut bits = 0;
         for item in self.iter() {
             bits |= item.to_uint();
         }
-        s.emit_uint(bits);
+        s.emit_uint(bits)
     }
 }
 
 impl<
-    D: Decoder,
-    T: Decodable<D> + CLike
-> Decodable<D> for EnumSet<T> {
-    fn decode(d: &mut D) -> EnumSet<T> {
-        let bits = d.read_uint();
+    E,
+    D: Decoder<E>,
+    T: Decodable<D, E> + CLike
+> Decodable<D, E> for EnumSet<T> {
+    fn decode(d: &mut D) -> Result<EnumSet<T>, E> {
+        let bits = try!(d.read_uint());
         let mut set = EnumSet::empty();
         for bit in range(0, uint::BITS) {
             if bits & (1 << bit) != 0 {
                 set.add(CLike::from_uint(1 << bit));
             }
         }
-        set
+        Ok(set)
     }
 }
 
 impl<
-    E: Encoder,
-    K: Encodable<E> + Hash<S> + TotalEq,
-    V: Encodable<E>,
-    S,
-    H: Hasher<S>
-> Encodable<E> for HashMap<K, V, H> {
-    fn encode(&self, e: &mut E) {
+    E,
+    S: Encoder<E>,
+    K: Encodable<S, E> + Hash<X> + TotalEq,
+    V: Encodable<S, E>,
+    X,
+    H: Hasher<X>
+> Encodable<S, E> for HashMap<K, V, H> {
+    fn encode(&self, e: &mut S) -> Result<(), E> {
         e.emit_map(self.len(), |e| {
             let mut i = 0;
             for (key, val) in self.iter() {
-                e.emit_map_elt_key(i, |e| key.encode(e));
-                e.emit_map_elt_val(i, |e| val.encode(e));
+                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
+                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                 i += 1;
             }
+            Ok(())
         })
     }
 }
 
 impl<
-    D: Decoder,
-    K: Decodable<D> + Hash<S> + TotalEq,
-    V: Decodable<D>,
+    E,
+    D: Decoder<E>,
+    K: Decodable<D, E> + Hash<S> + TotalEq,
+    V: Decodable<D, E>,
     S,
     H: Hasher<S> + Default
-> Decodable<D> for HashMap<K, V, H> {
-    fn decode(d: &mut D) -> HashMap<K, V, H> {
+> Decodable<D, E> for HashMap<K, V, H> {
+    fn decode(d: &mut D) -> Result<HashMap<K, V, H>, E> {
         d.read_map(|d, len| {
             let hasher = Default::default();
             let mut map = HashMap::with_capacity_and_hasher(len, hasher);
             for i in range(0u, len) {
-                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
-                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
+                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                 map.insert(key, val);
             }
-            map
+            Ok(map)
         })
     }
 }
 
 impl<
-    E: Encoder,
-    T: Encodable<E> + Hash<S> + TotalEq,
-    S,
-    H: Hasher<S>
-> Encodable<E> for HashSet<T, H> {
-    fn encode(&self, s: &mut E) {
+    E,
+    S: Encoder<E>,
+    T: Encodable<S, E> + Hash<X> + TotalEq,
+    X,
+    H: Hasher<X>
+> Encodable<S, E> for HashSet<T, H> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             let mut i = 0;
             for e in self.iter() {
-                s.emit_seq_elt(i, |s| e.encode(s));
+                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                 i += 1;
             }
+            Ok(())
         })
     }
 }
 
 impl<
-    D: Decoder,
-    T: Decodable<D> + Hash<S> + TotalEq,
+    E,
+    D: Decoder<E>,
+    T: Decodable<D, E> + Hash<S> + TotalEq,
     S,
     H: Hasher<S> + Default
-> Decodable<D> for HashSet<T, H> {
-    fn decode(d: &mut D) -> HashSet<T, H> {
+> Decodable<D, E> for HashSet<T, H> {
+    fn decode(d: &mut D) -> Result<HashSet<T, H>, E> {
         d.read_seq(|d, len| {
             let mut set = HashSet::with_capacity_and_hasher(len, Default::default());
             for i in range(0u, len) {
-                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-            set
+            Ok(set)
         })
     }
 }
 
 impl<
-    E: Encoder,
-    V: Encodable<E>
-> Encodable<E> for TrieMap<V> {
-    fn encode(&self, e: &mut E) {
+    E,
+    S: Encoder<E>,
+    V: Encodable<S, E>
+> Encodable<S, E> for TrieMap<V> {
+    fn encode(&self, e: &mut S) -> Result<(), E> {
         e.emit_map(self.len(), |e| {
                 for (i, (key, val)) in self.iter().enumerate() {
-                    e.emit_map_elt_key(i, |e| key.encode(e));
-                    e.emit_map_elt_val(i, |e| val.encode(e));
+                    try!(e.emit_map_elt_key(i, |e| key.encode(e)));
+                    try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                 }
-            });
+                Ok(())
+            })
     }
 }
 
 impl<
-    D: Decoder,
-    V: Decodable<D>
-> Decodable<D> for TrieMap<V> {
-    fn decode(d: &mut D) -> TrieMap<V> {
+    E,
+    D: Decoder<E>,
+    V: Decodable<D, E>
+> Decodable<D, E> for TrieMap<V> {
+    fn decode(d: &mut D) -> Result<TrieMap<V>, E> {
         d.read_map(|d, len| {
             let mut map = TrieMap::new();
             for i in range(0u, len) {
-                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
-                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
+                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                 map.insert(key, val);
             }
-            map
+            Ok(map)
         })
     }
 }
 
-impl<S: Encoder> Encodable<S> for TrieSet {
-    fn encode(&self, s: &mut S) {
+impl<E, S: Encoder<E>> Encodable<S, E> for TrieSet {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
                 for (i, e) in self.iter().enumerate() {
-                    s.emit_seq_elt(i, |s| e.encode(s));
+                    try!(s.emit_seq_elt(i, |s| e.encode(s)));
                 }
+                Ok(())
             })
     }
 }
 
-impl<D: Decoder> Decodable<D> for TrieSet {
-    fn decode(d: &mut D) -> TrieSet {
+impl<E, D: Decoder<E>> Decodable<D, E> for TrieSet {
+    fn decode(d: &mut D) -> Result<TrieSet, E> {
         d.read_seq(|d, len| {
             let mut set = TrieSet::new();
             for i in range(0u, len) {
-                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
             }
-            set
+            Ok(set)
         })
     }
 }
diff --git a/src/libserialize/collection_impls_old.rs b/src/libserialize/collection_impls_old.rs
new file mode 100644
index 00000000000..5994fbc5d10
--- /dev/null
+++ b/src/libserialize/collection_impls_old.rs
@@ -0,0 +1,292 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementations of serialization for structures found in libcollections
+
+use std::uint;
+use std::default::Default;
+use std::hash::{Hash, Hasher};
+
+use {Decodable, Encodable, Decoder, Encoder};
+use collections::{DList, RingBuf, TreeMap, TreeSet, Deque, HashMap, HashSet,
+                  TrieMap, TrieSet};
+use collections::enum_set::{EnumSet, CLike};
+
+impl<
+    S: Encoder,
+    T: Encodable<S>
+> Encodable<S> for DList<T> {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s));
+            }
+        })
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> {
+    fn decode(d: &mut D) -> DList<T> {
+        let mut list = DList::new();
+        d.read_seq(|d, len| {
+            for i in range(0u, len) {
+                list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
+            }
+        });
+        list
+    }
+}
+
+impl<
+    S: Encoder,
+    T: Encodable<S>
+> Encodable<S> for RingBuf<T> {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s));
+            }
+        })
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> {
+    fn decode(d: &mut D) -> RingBuf<T> {
+        let mut deque = RingBuf::new();
+        d.read_seq(|d, len| {
+            for i in range(0u, len) {
+                deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
+            }
+        });
+        deque
+    }
+}
+
+impl<
+    E: Encoder,
+    K: Encodable<E> + Eq + TotalOrd,
+    V: Encodable<E> + Eq
+> Encodable<E> for TreeMap<K, V> {
+    fn encode(&self, e: &mut E) {
+        e.emit_map(self.len(), |e| {
+            let mut i = 0;
+            for (key, val) in self.iter() {
+                e.emit_map_elt_key(i, |e| key.encode(e));
+                e.emit_map_elt_val(i, |e| val.encode(e));
+                i += 1;
+            }
+        })
+    }
+}
+
+impl<
+    D: Decoder,
+    K: Decodable<D> + Eq + TotalOrd,
+    V: Decodable<D> + Eq
+> Decodable<D> for TreeMap<K, V> {
+    fn decode(d: &mut D) -> TreeMap<K, V> {
+        d.read_map(|d, len| {
+            let mut map = TreeMap::new();
+            for i in range(0u, len) {
+                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
+                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                map.insert(key, val);
+            }
+            map
+        })
+    }
+}
+
+impl<
+    S: Encoder,
+    T: Encodable<S> + Eq + TotalOrd
+> Encodable<S> for TreeSet<T> {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            let mut i = 0;
+            for e in self.iter() {
+                s.emit_seq_elt(i, |s| e.encode(s));
+                i += 1;
+            }
+        })
+    }
+}
+
+impl<
+    D: Decoder,
+    T: Decodable<D> + Eq + TotalOrd
+> Decodable<D> for TreeSet<T> {
+    fn decode(d: &mut D) -> TreeSet<T> {
+        d.read_seq(|d, len| {
+            let mut set = TreeSet::new();
+            for i in range(0u, len) {
+                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+            }
+            set
+        })
+    }
+}
+
+impl<
+    S: Encoder,
+    T: Encodable<S> + CLike
+> Encodable<S> for EnumSet<T> {
+    fn encode(&self, s: &mut S) {
+        let mut bits = 0;
+        for item in self.iter() {
+            bits |= item.to_uint();
+        }
+        s.emit_uint(bits);
+    }
+}
+
+impl<
+    D: Decoder,
+    T: Decodable<D> + CLike
+> Decodable<D> for EnumSet<T> {
+    fn decode(d: &mut D) -> EnumSet<T> {
+        let bits = d.read_uint();
+        let mut set = EnumSet::empty();
+        for bit in range(0, uint::BITS) {
+            if bits & (1 << bit) != 0 {
+                set.add(CLike::from_uint(1 << bit));
+            }
+        }
+        set
+    }
+}
+
+impl<
+    E: Encoder,
+    K: Encodable<E> + Hash<S> + TotalEq,
+    V: Encodable<E>,
+    S,
+    H: Hasher<S>
+> Encodable<E> for HashMap<K, V, H> {
+    fn encode(&self, e: &mut E) {
+        e.emit_map(self.len(), |e| {
+            let mut i = 0;
+            for (key, val) in self.iter() {
+                e.emit_map_elt_key(i, |e| key.encode(e));
+                e.emit_map_elt_val(i, |e| val.encode(e));
+                i += 1;
+            }
+        })
+    }
+}
+
+impl<
+    D: Decoder,
+    K: Decodable<D> + Hash<S> + TotalEq,
+    V: Decodable<D>,
+    S,
+    H: Hasher<S> + Default
+> Decodable<D> for HashMap<K, V, H> {
+    fn decode(d: &mut D) -> HashMap<K, V, H> {
+        d.read_map(|d, len| {
+            let hasher = Default::default();
+            let mut map = HashMap::with_capacity_and_hasher(len, hasher);
+            for i in range(0u, len) {
+                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
+                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                map.insert(key, val);
+            }
+            map
+        })
+    }
+}
+
+impl<
+    E: Encoder,
+    T: Encodable<E> + Hash<S> + TotalEq,
+    S,
+    H: Hasher<S>
+> Encodable<E> for HashSet<T, H> {
+    fn encode(&self, s: &mut E) {
+        s.emit_seq(self.len(), |s| {
+            let mut i = 0;
+            for e in self.iter() {
+                s.emit_seq_elt(i, |s| e.encode(s));
+                i += 1;
+            }
+        })
+    }
+}
+
+impl<
+    D: Decoder,
+    T: Decodable<D> + Hash<S> + TotalEq,
+    S,
+    H: Hasher<S> + Default
+> Decodable<D> for HashSet<T, H> {
+    fn decode(d: &mut D) -> HashSet<T, H> {
+        d.read_seq(|d, len| {
+            let mut set = HashSet::with_capacity_and_hasher(len, Default::default());
+            for i in range(0u, len) {
+                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+            }
+            set
+        })
+    }
+}
+
+impl<
+    E: Encoder,
+    V: Encodable<E>
+> Encodable<E> for TrieMap<V> {
+    fn encode(&self, e: &mut E) {
+        e.emit_map(self.len(), |e| {
+                for (i, (key, val)) in self.iter().enumerate() {
+                    e.emit_map_elt_key(i, |e| key.encode(e));
+                    e.emit_map_elt_val(i, |e| val.encode(e));
+                }
+            });
+    }
+}
+
+impl<
+    D: Decoder,
+    V: Decodable<D>
+> Decodable<D> for TrieMap<V> {
+    fn decode(d: &mut D) -> TrieMap<V> {
+        d.read_map(|d, len| {
+            let mut map = TrieMap::new();
+            for i in range(0u, len) {
+                let key = d.read_map_elt_key(i, |d| Decodable::decode(d));
+                let val = d.read_map_elt_val(i, |d| Decodable::decode(d));
+                map.insert(key, val);
+            }
+            map
+        })
+    }
+}
+
+impl<S: Encoder> Encodable<S> for TrieSet {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+                for (i, e) in self.iter().enumerate() {
+                    s.emit_seq_elt(i, |s| e.encode(s));
+                }
+            })
+    }
+}
+
+impl<D: Decoder> Decodable<D> for TrieSet {
+    fn decode(d: &mut D) -> TrieSet {
+        d.read_seq(|d, len| {
+            let mut set = TrieSet::new();
+            for i in range(0u, len) {
+                set.insert(d.read_seq_elt(i, |d| Decodable::decode(d)));
+            }
+            set
+        })
+    }
+}
+
diff --git a/src/libserialize/ebml.rs b/src/libserialize/ebml.rs
index 2b416f263c2..cc2385665a2 100644
--- a/src/libserialize/ebml.rs
+++ b/src/libserialize/ebml.rs
@@ -10,12 +10,9 @@
 
 #[allow(missing_doc)];
 
+use std::io;
 use std::str;
 
-macro_rules! try( ($e:expr) => (
-    match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } }
-) )
-
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
@@ -79,6 +76,13 @@ pub enum EbmlEncoderTag {
 
     EsLabel, // Used only when debugging
 }
+
+#[deriving(Show)]
+pub enum Error {
+    IntTooBig(uint),
+    Expected(~str),
+    IoError(io::IoError)
+}
 // --------------------------------------
 
 pub mod reader {
@@ -94,43 +98,57 @@ pub mod reader {
     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 };
+        EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, Error, IntTooBig,
+        Expected };
 
+    pub type DecodeResult<T> = Result<T, Error>;
     // ebml reading
 
+    macro_rules! try_or(
+        ($e:expr, $r:expr) => (
+            match $e {
+                Ok(e) => e,
+                Err(e) => {
+                    debug!("ignored error: {}", e);
+                    return $r
+                }
+            }
+        )
+    )
+
     pub struct Res {
         val: uint,
         next: uint
     }
 
     #[inline(never)]
-    fn vuint_at_slow(data: &[u8], start: uint) -> Res {
+    fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
         let a = data[start];
         if a & 0x80u8 != 0u8 {
-            return Res {val: (a & 0x7fu8) as uint, next: start + 1u};
+            return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
         }
         if a & 0x40u8 != 0u8 {
-            return Res {val: ((a & 0x3fu8) as uint) << 8u |
+            return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
                         (data[start + 1u] as uint),
-                    next: start + 2u};
+                    next: start + 2u});
         }
         if a & 0x20u8 != 0u8 {
-            return Res {val: ((a & 0x1fu8) as uint) << 16u |
+            return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
                         (data[start + 1u] as uint) << 8u |
                         (data[start + 2u] as uint),
-                    next: start + 3u};
+                    next: start + 3u});
         }
         if a & 0x10u8 != 0u8 {
-            return Res {val: ((a & 0x0fu8) as uint) << 24u |
+            return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
                         (data[start + 1u] as uint) << 16u |
                         (data[start + 2u] as uint) << 8u |
                         (data[start + 3u] as uint),
-                    next: start + 4u};
+                    next: start + 4u});
         }
-        fail!("vint too big");
+        Err(IntTooBig(a as uint))
     }
 
-    pub fn vuint_at(data: &[u8], start: uint) -> Res {
+    pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
         use std::mem::from_be32;
 
         if data.len() - start < 4 {
@@ -166,10 +184,10 @@ pub mod reader {
 
             let i = (val >> 28u) as uint;
             let (shift, mask) = SHIFT_MASK_TABLE[i];
-            Res {
+            Ok(Res {
                 val: ((val >> shift) & mask) as uint,
                 next: start + (((32 - shift) >> 3) as uint)
-            }
+            })
         }
     }
 
@@ -177,21 +195,21 @@ pub mod reader {
         Doc { data: data, start: 0u, end: data.len() }
     }
 
-    pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> {
-        let elt_tag = vuint_at(data, start);
-        let elt_size = vuint_at(data, elt_tag.next);
+    pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
+        let elt_tag = try!(vuint_at(data, start));
+        let elt_size = try!(vuint_at(data, elt_tag.next));
         let end = elt_size.next + elt_size.val;
-        TaggedDoc {
+        Ok(TaggedDoc {
             tag: elt_tag.val,
             doc: Doc { data: data, start: elt_size.next, end: end }
-        }
+        })
     }
 
     pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = vuint_at(d.data, pos);
-            let elt_size = vuint_at(d.data, elt_tag.next);
+            let elt_tag = try_or!(vuint_at(d.data, pos), None);
+            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
             pos = elt_size.next + elt_size.val;
             if elt_tag.val == tg {
                 return Some(Doc { data: d.data, start: elt_size.next,
@@ -214,8 +232,8 @@ pub mod reader {
     pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = vuint_at(d.data, pos);
-            let elt_size = vuint_at(d.data, elt_tag.next);
+            let elt_tag = try_or!(vuint_at(d.data, pos), false);
+            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
             pos = elt_size.next + elt_size.val;
             let doc = Doc { data: d.data, start: elt_size.next, end: pos };
             if !it(elt_tag.val, doc) {
@@ -228,8 +246,8 @@ pub mod reader {
     pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = vuint_at(d.data, pos);
-            let elt_size = vuint_at(d.data, elt_tag.next);
+            let elt_tag = try_or!(vuint_at(d.data, pos), false);
+            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
             pos = elt_size.next + elt_size.val;
             if elt_tag.val == tg {
                 let doc = Doc { data: d.data, start: elt_size.next,
@@ -285,28 +303,29 @@ pub mod reader {
     }
 
     impl<'doc> Decoder<'doc> {
-        fn _check_label(&mut self, lbl: &str) {
+        fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
             if self.pos < self.parent.end {
                 let TaggedDoc { tag: r_tag, doc: r_doc } =
-                    doc_at(self.parent.data, self.pos);
+                    try!(doc_at(self.parent.data, self.pos));
 
                 if r_tag == (EsLabel as uint) {
                     self.pos = r_doc.end;
                     let str = r_doc.as_str_slice();
                     if lbl != str {
-                        fail!("Expected label {} but found {}", lbl, str);
+                        return Err(Expected(format!("Expected label {} but found {}", lbl, str)));
                     }
                 }
             }
+            Ok(())
         }
 
-        fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> {
+        fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
             debug!(". next_doc(exp_tag={:?})", exp_tag);
             if self.pos >= self.parent.end {
-                fail!("no more documents in current node!");
+                return Err(Expected(format!("no more documents in current node!")));
             }
             let TaggedDoc { tag: r_tag, doc: r_doc } =
-                doc_at(self.parent.data, self.pos);
+                try!(doc_at(self.parent.data, self.pos));
             debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
                    self.parent.start,
                    self.parent.end,
@@ -315,178 +334,183 @@ pub mod reader {
                    r_doc.start,
                    r_doc.end);
             if r_tag != (exp_tag as uint) {
-                fail!("expected EBML doc with tag {:?} but found tag {:?}",
-                       exp_tag, r_tag);
+                return Err(Expected(format!("expected EBML doc with tag {:?} but found tag {:?}",
+                       exp_tag, r_tag)));
             }
             if r_doc.end > self.parent.end {
-                fail!("invalid EBML, child extends to {:#x}, parent to {:#x}",
-                      r_doc.end, self.parent.end);
+                return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to {:#x}",
+                      r_doc.end, self.parent.end)));
             }
             self.pos = r_doc.end;
-            r_doc
+            Ok(r_doc)
         }
 
         fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
-                       f: |&mut Decoder<'doc>| -> T) -> T {
-            let d = self.next_doc(exp_tag);
+                       f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
+            let d = try!(self.next_doc(exp_tag));
             let old_parent = self.parent;
             let old_pos = self.pos;
             self.parent = d;
             self.pos = d.start;
-            let r = f(self);
+            let r = try!(f(self));
             self.parent = old_parent;
             self.pos = old_pos;
-            r
+            Ok(r)
         }
 
-        fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
-            let r = doc_as_u32(self.next_doc(exp_tag));
+        fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
+            let r = doc_as_u32(try!(self.next_doc(exp_tag)));
             debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
-            r as uint
+            Ok(r as uint)
         }
 
-        pub fn read_opaque<R>(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R {
-            let doc = self.next_doc(EsOpaque);
+        pub fn read_opaque<R>(&mut self,
+                              op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> {
+            let doc = try!(self.next_doc(EsOpaque));
 
             let (old_parent, old_pos) = (self.parent, self.pos);
             self.parent = doc;
             self.pos = doc.start;
 
-            let result = op(self, doc);
+            let result = try!(op(self, doc));
 
             self.parent = old_parent;
             self.pos = old_pos;
-            result
+            Ok(result)
         }
     }
 
-    impl<'doc> serialize::Decoder for Decoder<'doc> {
-        fn read_nil(&mut self) -> () { () }
+    impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
+        fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
 
-        fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
-        fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
-        fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
-        fn read_u8 (&mut self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
-        fn read_uint(&mut self) -> uint {
-            let v = doc_as_u64(self.next_doc(EsUint));
+        fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
+        fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
+        fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
+        fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
+        fn read_uint(&mut self) -> DecodeResult<uint> {
+            let v = doc_as_u64(try!(self.next_doc(EsUint)));
             if v > (::std::uint::MAX as u64) {
-                fail!("uint {} too large for this architecture", v);
+                Err(IntTooBig(v as uint))
+            } else {
+                Ok(v as uint)
             }
-            v as uint
         }
 
-        fn read_i64(&mut self) -> i64 {
-            doc_as_u64(self.next_doc(EsI64)) as i64
+        fn read_i64(&mut self) -> DecodeResult<i64> {
+            Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
         }
-        fn read_i32(&mut self) -> i32 {
-            doc_as_u32(self.next_doc(EsI32)) as i32
+        fn read_i32(&mut self) -> DecodeResult<i32> {
+            Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
         }
-        fn read_i16(&mut self) -> i16 {
-            doc_as_u16(self.next_doc(EsI16)) as i16
+        fn read_i16(&mut self) -> DecodeResult<i16> {
+            Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
         }
-        fn read_i8 (&mut self) -> i8 {
-            doc_as_u8(self.next_doc(EsI8 )) as i8
+        fn read_i8 (&mut self) -> DecodeResult<i8> {
+            Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
         }
-        fn read_int(&mut self) -> int {
-            let v = doc_as_u64(self.next_doc(EsInt)) as i64;
+        fn read_int(&mut self) -> DecodeResult<int> {
+            let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
             if v > (int::MAX as i64) || v < (int::MIN as i64) {
                 debug!("FIXME \\#6122: Removing this makes this function miscompile");
-                fail!("int {} out of range for this architecture", v);
+                Err(IntTooBig(v as uint))
+            } else {
+                Ok(v as int)
             }
-            v as int
         }
 
-        fn read_bool(&mut self) -> bool {
-            doc_as_u8(self.next_doc(EsBool)) != 0
+        fn read_bool(&mut self) -> DecodeResult<bool> {
+            Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
         }
 
-        fn read_f64(&mut self) -> f64 {
-            let bits = doc_as_u64(self.next_doc(EsF64));
-            unsafe { transmute(bits) }
+        fn read_f64(&mut self) -> DecodeResult<f64> {
+            let bits = doc_as_u64(try!(self.next_doc(EsF64)));
+            Ok(unsafe { transmute(bits) })
         }
-        fn read_f32(&mut self) -> f32 {
-            let bits = doc_as_u32(self.next_doc(EsF32));
-            unsafe { transmute(bits) }
+        fn read_f32(&mut self) -> DecodeResult<f32> {
+            let bits = doc_as_u32(try!(self.next_doc(EsF32)));
+            Ok(unsafe { transmute(bits) })
         }
-        fn read_char(&mut self) -> char {
-            char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
+        fn read_char(&mut self) -> DecodeResult<char> {
+            Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
         }
-        fn read_str(&mut self) -> ~str {
-            self.next_doc(EsStr).as_str()
+        fn read_str(&mut self) -> DecodeResult<~str> {
+            Ok(try!(self.next_doc(EsStr)).as_str())
         }
 
         // Compound types:
-        fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T {
+        fn read_enum<T>(&mut self,
+                        name: &str,
+                        f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_enum({})", name);
-            self._check_label(name);
+            try!(self._check_label(name));
 
-            let doc = self.next_doc(EsEnum);
+            let doc = try!(self.next_doc(EsEnum));
 
             let (old_parent, old_pos) = (self.parent, self.pos);
             self.parent = doc;
             self.pos = self.parent.start;
 
-            let result = f(self);
+            let result = try!(f(self));
 
             self.parent = old_parent;
             self.pos = old_pos;
-            result
+            Ok(result)
         }
 
         fn read_enum_variant<T>(&mut self,
                                 _: &[&str],
-                                f: |&mut Decoder<'doc>, uint| -> T)
-                                -> T {
+                                f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
+                                -> DecodeResult<T> {
             debug!("read_enum_variant()");
-            let idx = self._next_uint(EsEnumVid);
+            let idx = try!(self._next_uint(EsEnumVid));
             debug!("  idx={}", idx);
 
-            let doc = self.next_doc(EsEnumBody);
+            let doc = try!(self.next_doc(EsEnumBody));
 
             let (old_parent, old_pos) = (self.parent, self.pos);
             self.parent = doc;
             self.pos = self.parent.start;
 
-            let result = f(self, idx);
+            let result = try!(f(self, idx));
 
             self.parent = old_parent;
             self.pos = old_pos;
-            result
+            Ok(result)
         }
 
         fn read_enum_variant_arg<T>(&mut self,
                                     idx: uint,
-                                    f: |&mut Decoder<'doc>| -> T) -> T {
+                                    f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_enum_variant_arg(idx={})", idx);
             f(self)
         }
 
         fn read_enum_struct_variant<T>(&mut self,
                                        _: &[&str],
-                                       f: |&mut Decoder<'doc>, uint| -> T)
-                                       -> T {
+                                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
+                                       -> DecodeResult<T> {
             debug!("read_enum_struct_variant()");
-            let idx = self._next_uint(EsEnumVid);
+            let idx = try!(self._next_uint(EsEnumVid));
             debug!("  idx={}", idx);
 
-            let doc = self.next_doc(EsEnumBody);
+            let doc = try!(self.next_doc(EsEnumBody));
 
             let (old_parent, old_pos) = (self.parent, self.pos);
             self.parent = doc;
             self.pos = self.parent.start;
 
-            let result = f(self, idx);
+            let result = try!(f(self, idx));
 
             self.parent = old_parent;
             self.pos = old_pos;
-            result
+            Ok(result)
         }
 
         fn read_enum_struct_variant_field<T>(&mut self,
                                              name: &str,
                                              idx: uint,
-                                             f: |&mut Decoder<'doc>| -> T)
-                                             -> T {
+                                             f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                                             -> DecodeResult<T> {
             debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
             f(self)
         }
@@ -494,8 +518,8 @@ pub mod reader {
         fn read_struct<T>(&mut self,
                           name: &str,
                           _: uint,
-                          f: |&mut Decoder<'doc>| -> T)
-                          -> T {
+                          f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                          -> DecodeResult<T> {
             debug!("read_struct(name={})", name);
             f(self)
         }
@@ -503,85 +527,89 @@ pub mod reader {
         fn read_struct_field<T>(&mut self,
                                 name: &str,
                                 idx: uint,
-                                f: |&mut Decoder<'doc>| -> T)
-                                -> T {
+                                f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                                -> DecodeResult<T> {
             debug!("read_struct_field(name={}, idx={})", name, idx);
-            self._check_label(name);
+            try!(self._check_label(name));
             f(self)
         }
 
-        fn read_tuple<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+        fn read_tuple<T>(&mut self,
+                         f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_tuple()");
             self.read_seq(f)
         }
 
-        fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
-                             -> T {
+        fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> 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<'doc>, uint| -> T)
-                                -> T {
+                                f: |&mut Decoder<'doc>, 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<'doc>| -> T)
-                                    -> T {
+                                    f: |&mut Decoder<'doc>| -> 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<'doc>, bool| -> T) -> T {
+        fn read_option<T>(&mut self,
+                          f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_option()");
             self.read_enum("Option", |this| {
                 this.read_enum_variant(["None", "Some"], |this, idx| {
                     match idx {
                         0 => f(this, false),
                         1 => f(this, true),
-                        _ => fail!(),
+                        _ => Err(Expected(format!("Expected None or Some"))),
                     }
                 })
             })
         }
 
-        fn read_seq<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+        fn read_seq<T>(&mut self,
+                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_seq()");
             self.push_doc(EsVec, |d| {
-                let len = d._next_uint(EsVecLen);
+                let len = try!(d._next_uint(EsVecLen));
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
-                           -> T {
+        fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                           -> DecodeResult<T> {
             debug!("read_seq_elt(idx={})", idx);
             self.push_doc(EsVecElt, f)
         }
 
-        fn read_map<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+        fn read_map<T>(&mut self,
+                       f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
             debug!("read_map()");
             self.push_doc(EsMap, |d| {
-                let len = d._next_uint(EsMapLen);
+                let len = try!(d._next_uint(EsMapLen));
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
-                               -> T {
+        fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                               -> DecodeResult<T> {
             debug!("read_map_elt_key(idx={})", idx);
             self.push_doc(EsMapKey, f)
         }
 
-        fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
-                               -> T {
+        fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
+                               -> DecodeResult<T> {
             debug!("read_map_elt_val(idx={})", idx);
             self.push_doc(EsMapVal, f)
         }
@@ -593,7 +621,6 @@ pub mod writer {
     use std::clone::Clone;
     use std::io;
     use std::io::{Writer, Seek};
-    use std::io::MemWriter;
     use std::io::extensions::u64_to_be_bytes;
 
     use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
@@ -603,20 +630,16 @@ pub mod writer {
 
     use serialize;
 
+
+    pub type EncodeResult = io::IoResult<()>;
+
     // ebml writing
-    pub struct Encoder<'a> {
-        // FIXME(#5665): this should take a trait object. Note that if you
-        //               delete this comment you should consider removing the
-        //               unwrap()'s below of the results of the calls to
-        //               write(). We're guaranteed that writing into a MemWriter
-        //               won't fail, but this is not true for all I/O streams in
-        //               general.
-        writer: &'a mut MemWriter,
+    pub struct Encoder<'a, W> {
+        writer: &'a mut W,
         priv size_positions: ~[uint],
-        last_error: io::IoResult<()>,
     }
 
-    fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
+    fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
         match size {
             1u => w.write(&[0x80u8 | (n as u8)]),
             2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
@@ -624,129 +647,136 @@ pub mod writer {
                             n as u8]),
             4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
                             (n >> 8_u) as u8, n as u8]),
-            _ => fail!("vint to write too big: {}", n)
-        }.unwrap()
+            _ => Err(io::IoError {
+                kind: io::OtherIoError,
+                desc: "int too big",
+                detail: Some(format!("{}", n))
+            })
+        }
     }
 
-    fn write_vuint(w: &mut MemWriter, n: uint) {
-        if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
-        if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
-        if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
-        if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
-        fail!("vint to write too big: {}", n);
+    fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+        if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
+        if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
+        if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
+        if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
+        Err(io::IoError {
+            kind: io::OtherIoError,
+            desc: "int too big",
+            detail: Some(format!("{}", n))
+        })
     }
 
-    pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
+    pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> {
         let size_positions: ~[uint] = ~[];
         Encoder {
             writer: w,
             size_positions: size_positions,
-            last_error: Ok(()),
         }
     }
 
     // FIXME (#2741): Provide a function to write the standard ebml header.
-    impl<'a> Encoder<'a> {
+    impl<'a, W: Writer + Seek> Encoder<'a, W> {
         /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
-        pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
+        pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
             Encoder {
                 writer: cast::transmute_copy(&self.writer),
                 size_positions: self.size_positions.clone(),
-                last_error: Ok(()),
             }
         }
 
-        pub fn start_tag(&mut self, tag_id: uint) {
+        pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
             debug!("Start tag {}", tag_id);
 
             // Write the enum ID:
-            write_vuint(self.writer, tag_id);
+            try!(write_vuint(self.writer, tag_id));
 
             // Write a placeholder four-byte size.
             self.size_positions.push(try!(self.writer.tell()) as uint);
             let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
-            try!(self.writer.write(zeroes));
+            self.writer.write(zeroes)
         }
 
-        pub fn end_tag(&mut self) {
+        pub fn end_tag(&mut self) -> EncodeResult {
             let last_size_pos = self.size_positions.pop().unwrap();
             let cur_pos = try!(self.writer.tell());
             try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
             let size = cur_pos as uint - last_size_pos - 4;
-            write_sized_vuint(self.writer, size, 4u);
-            try!(self.writer.seek(cur_pos as i64, io::SeekSet));
+            try!(write_sized_vuint(self.writer, size, 4u));
+            let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
 
             debug!("End tag (size = {})", size);
+            Ok(r)
         }
 
-        pub fn wr_tag(&mut self, tag_id: uint, blk: ||) {
-            self.start_tag(tag_id);
-            blk();
-            self.end_tag();
+        pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult {
+            try!(self.start_tag(tag_id));
+            try!(blk());
+            self.end_tag()
         }
 
-        pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
-            write_vuint(self.writer, tag_id);
-            write_vuint(self.writer, b.len());
-            self.writer.write(b).unwrap();
+        pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
+            try!(write_vuint(self.writer, tag_id));
+            try!(write_vuint(self.writer, b.len()));
+            self.writer.write(b)
         }
 
-        pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
+        pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
             u64_to_be_bytes(v, 8u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) {
+        pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32)  -> EncodeResult{
             u64_to_be_bytes(v as u64, 4u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) {
+        pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
             u64_to_be_bytes(v as u64, 2u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) {
-            self.wr_tagged_bytes(tag_id, &[v]);
+        pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
+            self.wr_tagged_bytes(tag_id, &[v])
         }
 
-        pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) {
+        pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
             u64_to_be_bytes(v as u64, 8u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) {
+        pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
             u64_to_be_bytes(v as u64, 4u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) {
+        pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
             u64_to_be_bytes(v as u64, 2u, |v| {
-                self.wr_tagged_bytes(tag_id, v);
+                self.wr_tagged_bytes(tag_id, v)
             })
         }
 
-        pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) {
-            self.wr_tagged_bytes(tag_id, &[v as u8]);
+        pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
+            self.wr_tagged_bytes(tag_id, &[v as u8])
         }
 
-        pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
-            self.wr_tagged_bytes(tag_id, v.as_bytes());
+        pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
+            self.wr_tagged_bytes(tag_id, v.as_bytes())
         }
 
-        pub fn wr_bytes(&mut self, b: &[u8]) {
+        pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
             debug!("Write {} bytes", b.len());
-            self.writer.write(b).unwrap();
+            self.writer.write(b)
         }
 
-        pub fn wr_str(&mut self, s: &str) {
+        pub fn wr_str(&mut self, s: &str) -> EncodeResult {
             debug!("Write str: {}", s);
-            self.writer.write(s.as_bytes()).unwrap();
+            self.writer.write(s.as_bytes())
         }
     }
 
@@ -757,14 +787,14 @@ pub mod writer {
     // Totally lame approach.
     static DEBUG: bool = true;
 
-    impl<'a> Encoder<'a> {
+    impl<'a, W: Writer + Seek> Encoder<'a, W> {
         // used internally to emit things like the vector length and so on
-        fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
+        fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
             assert!(v <= 0xFFFF_FFFF_u);
-            self.wr_tagged_u32(t as uint, v as u32);
+            self.wr_tagged_u32(t as uint, v as u32)
         }
 
-        fn _emit_label(&mut self, label: &str) {
+        fn _emit_label(&mut self, label: &str) -> EncodeResult {
             // There are various strings that we have access to, such as
             // the name of a record field, which do not actually appear in
             // the encoded EBML (normally).  This is just for
@@ -772,89 +802,96 @@ pub mod writer {
             // labels and then they will be checked by decoder to
             // try and check failures more quickly.
             if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
+            else { Ok(()) }
         }
 
-        pub fn emit_opaque(&mut self, f: |&mut Encoder|) {
-            self.start_tag(EsOpaque as uint);
-            f(self);
-            self.end_tag();
+        pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult {
+            try!(self.start_tag(EsOpaque as uint));
+            try!(f(self));
+            self.end_tag()
         }
     }
 
-    impl<'a> serialize::Encoder for Encoder<'a> {
-        fn emit_nil(&mut self) {}
+    impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
+        fn emit_nil(&mut self) -> EncodeResult {
+            Ok(())
+        }
 
-        fn emit_uint(&mut self, v: uint) {
-            self.wr_tagged_u64(EsUint as uint, v as u64);
+        fn emit_uint(&mut self, v: uint) -> EncodeResult {
+            self.wr_tagged_u64(EsUint as uint, v as u64)
         }
-        fn emit_u64(&mut self, v: u64) {
-            self.wr_tagged_u64(EsU64 as uint, v);
+        fn emit_u64(&mut self, v: u64) -> EncodeResult {
+            self.wr_tagged_u64(EsU64 as uint, v)
         }
-        fn emit_u32(&mut self, v: u32) {
-            self.wr_tagged_u32(EsU32 as uint, v);
+        fn emit_u32(&mut self, v: u32) -> EncodeResult {
+            self.wr_tagged_u32(EsU32 as uint, v)
         }
-        fn emit_u16(&mut self, v: u16) {
-            self.wr_tagged_u16(EsU16 as uint, v);
+        fn emit_u16(&mut self, v: u16) -> EncodeResult {
+            self.wr_tagged_u16(EsU16 as uint, v)
         }
-        fn emit_u8(&mut self, v: u8) {
-            self.wr_tagged_u8(EsU8 as uint, v);
+        fn emit_u8(&mut self, v: u8) -> EncodeResult {
+            self.wr_tagged_u8(EsU8 as uint, v)
         }
 
-        fn emit_int(&mut self, v: int) {
-            self.wr_tagged_i64(EsInt as uint, v as i64);
+        fn emit_int(&mut self, v: int) -> EncodeResult {
+            self.wr_tagged_i64(EsInt as uint, v as i64)
         }
-        fn emit_i64(&mut self, v: i64) {
-            self.wr_tagged_i64(EsI64 as uint, v);
+        fn emit_i64(&mut self, v: i64) -> EncodeResult {
+            self.wr_tagged_i64(EsI64 as uint, v)
         }
-        fn emit_i32(&mut self, v: i32) {
-            self.wr_tagged_i32(EsI32 as uint, v);
+        fn emit_i32(&mut self, v: i32) -> EncodeResult {
+            self.wr_tagged_i32(EsI32 as uint, v)
         }
-        fn emit_i16(&mut self, v: i16) {
-            self.wr_tagged_i16(EsI16 as uint, v);
+        fn emit_i16(&mut self, v: i16) -> EncodeResult {
+            self.wr_tagged_i16(EsI16 as uint, v)
         }
-        fn emit_i8(&mut self, v: i8) {
-            self.wr_tagged_i8(EsI8 as uint, v);
+        fn emit_i8(&mut self, v: i8) -> EncodeResult {
+            self.wr_tagged_i8(EsI8 as uint, v)
         }
 
-        fn emit_bool(&mut self, v: bool) {
+        fn emit_bool(&mut self, v: bool) -> EncodeResult {
             self.wr_tagged_u8(EsBool as uint, v as u8)
         }
 
-        fn emit_f64(&mut self, v: f64) {
+        fn emit_f64(&mut self, v: f64) -> EncodeResult {
             let bits = unsafe { cast::transmute(v) };
-            self.wr_tagged_u64(EsF64 as uint, bits);
+            self.wr_tagged_u64(EsF64 as uint, bits)
         }
-        fn emit_f32(&mut self, v: f32) {
+        fn emit_f32(&mut self, v: f32) -> EncodeResult {
             let bits = unsafe { cast::transmute(v) };
-            self.wr_tagged_u32(EsF32 as uint, bits);
+            self.wr_tagged_u32(EsF32 as uint, bits)
         }
-        fn emit_char(&mut self, v: char) {
-            self.wr_tagged_u32(EsChar as uint, v as u32);
+        fn emit_char(&mut self, v: char) -> EncodeResult {
+            self.wr_tagged_u32(EsChar as uint, v as u32)
         }
 
-        fn emit_str(&mut self, v: &str) {
+        fn emit_str(&mut self, v: &str) -> EncodeResult {
             self.wr_tagged_str(EsStr as uint, v)
         }
 
-        fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) {
-            self._emit_label(name);
-            self.start_tag(EsEnum as uint);
-            f(self);
-            self.end_tag();
+        fn emit_enum(&mut self,
+                     name: &str,
+                     f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+            try!(self._emit_label(name));
+            try!(self.start_tag(EsEnum as uint));
+            try!(f(self));
+            self.end_tag()
         }
 
         fn emit_enum_variant(&mut self,
                              _: &str,
                              v_id: uint,
                              _: uint,
-                             f: |&mut Encoder<'a>|) {
-            self._emit_tagged_uint(EsEnumVid, v_id);
-            self.start_tag(EsEnumBody as uint);
-            f(self);
-            self.end_tag();
+                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+            try!(self._emit_tagged_uint(EsEnumVid, v_id));
+            try!(self.start_tag(EsEnumBody as uint));
+            try!(f(self));
+            self.end_tag()
         }
 
-        fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) {
+        fn emit_enum_variant_arg(&mut self,
+                                 _: uint,
+                                 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
             f(self)
         }
 
@@ -862,91 +899,113 @@ pub mod writer {
                                     v_name: &str,
                                     v_id: uint,
                                     cnt: uint,
-                                    f: |&mut Encoder<'a>|) {
+                                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
             self.emit_enum_variant(v_name, v_id, cnt, f)
         }
 
         fn emit_enum_struct_variant_field(&mut self,
                                           _: &str,
                                           idx: uint,
-                                          f: |&mut Encoder<'a>|) {
+                                          f: |&mut Encoder<'a, W>| -> EncodeResult)
+            -> EncodeResult {
             self.emit_enum_variant_arg(idx, f)
         }
 
         fn emit_struct(&mut self,
                        _: &str,
                        _len: uint,
-                       f: |&mut Encoder<'a>|) {
+                       f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
             f(self)
         }
 
         fn emit_struct_field(&mut self,
                              name: &str,
                              _: uint,
-                             f: |&mut Encoder<'a>|) {
-            self._emit_label(name);
+                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+            try!(self._emit_label(name));
             f(self)
         }
 
-        fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) {
+        fn emit_tuple(&mut self,
+                      len: uint,
+                      f: |&mut Encoder<'a, W>| -> 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, W>| -> EncodeResult) -> EncodeResult {
             self.emit_seq_elt(idx, f)
         }
 
         fn emit_tuple_struct(&mut self,
                              _: &str,
                              len: uint,
-                             f: |&mut Encoder<'a>|) {
+                             f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
             self.emit_seq(len, f)
         }
         fn emit_tuple_struct_arg(&mut self,
                                  idx: uint,
-                                 f: |&mut Encoder<'a>|) {
+                                 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
             self.emit_seq_elt(idx, f)
         }
 
-        fn emit_option(&mut self, f: |&mut Encoder<'a>|) {
-            self.emit_enum("Option", f);
+        fn emit_option(&mut self,
+                       f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+            self.emit_enum("Option", f)
         }
-        fn emit_option_none(&mut self) {
-            self.emit_enum_variant("None", 0, 0, |_| ())
+        fn emit_option_none(&mut self) -> EncodeResult {
+            self.emit_enum_variant("None", 0, 0, |_| Ok(()))
         }
-        fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) {
+        fn emit_option_some(&mut self,
+                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+
             self.emit_enum_variant("Some", 1, 1, f)
         }
 
-        fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) {
-            self.start_tag(EsVec as uint);
-            self._emit_tagged_uint(EsVecLen, len);
-            f(self);
-            self.end_tag();
+        fn emit_seq(&mut self,
+                    len: uint,
+                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+
+            try!(self.start_tag(EsVec as uint));
+            try!(self._emit_tagged_uint(EsVecLen, len));
+            try!(f(self));
+            self.end_tag()
         }
 
-        fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
-            self.start_tag(EsVecElt as uint);
-            f(self);
-            self.end_tag();
+        fn emit_seq_elt(&mut self,
+                        _idx: uint,
+                        f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+
+            try!(self.start_tag(EsVecElt as uint));
+            try!(f(self));
+            self.end_tag()
         }
 
-        fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) {
-            self.start_tag(EsMap as uint);
-            self._emit_tagged_uint(EsMapLen, len);
-            f(self);
-            self.end_tag();
+        fn emit_map(&mut self,
+                    len: uint,
+                    f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+
+            try!(self.start_tag(EsMap as uint));
+            try!(self._emit_tagged_uint(EsMapLen, len));
+            try!(f(self));
+            self.end_tag()
         }
 
-        fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
-            self.start_tag(EsMapKey as uint);
-            f(self);
-            self.end_tag();
+        fn emit_map_elt_key(&mut self,
+                            _idx: uint,
+                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+
+            try!(self.start_tag(EsMapKey as uint));
+            try!(f(self));
+            self.end_tag()
         }
 
-        fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
-            self.start_tag(EsMapVal as uint);
-            f(self);
-            self.end_tag();
+        fn emit_map_elt_val(&mut self,
+                            _idx: uint,
+                            f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
+            try!(self.start_tag(EsMapVal as uint));
+            try!(f(self));
+            self.end_tag()
         }
     }
 }
@@ -979,34 +1038,34 @@ mod tests {
         let mut res: reader::Res;
 
         // Class A
-        res = reader::vuint_at(data, 0);
+        res = reader::vuint_at(data, 0).unwrap();
         assert_eq!(res.val, 0);
         assert_eq!(res.next, 1);
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, (1 << 7) - 1);
         assert_eq!(res.next, 2);
 
         // Class B
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, 0);
         assert_eq!(res.next, 4);
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, (1 << 14) - 1);
         assert_eq!(res.next, 6);
 
         // Class C
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, 0);
         assert_eq!(res.next, 9);
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, (1 << 21) - 1);
         assert_eq!(res.next, 12);
 
         // Class D
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, 0);
         assert_eq!(res.next, 16);
-        res = reader::vuint_at(data, res.next);
+        res = reader::vuint_at(data, res.next).unwrap();
         assert_eq!(res.val, (1 << 28) - 1);
         assert_eq!(res.next, 20);
     }
@@ -1018,11 +1077,11 @@ mod tests {
             let mut wr = MemWriter::new();
             {
                 let mut ebml_w = writer::Encoder(&mut wr);
-                v.encode(&mut ebml_w);
+                let _ = v.encode(&mut ebml_w);
             }
             let ebml_doc = reader::Doc(wr.get_ref());
             let mut deser = reader::Decoder(ebml_doc);
-            let v1 = Decodable::decode(&mut deser);
+            let v1 = Decodable::decode(&mut deser).unwrap();
             debug!("v1 == {:?}", v1);
             assert_eq!(v, v1);
         }
@@ -1052,7 +1111,7 @@ mod bench {
         bh.iter(|| {
             let mut i = 0;
             while i < data.len() {
-                sum += reader::vuint_at(data, i).val;
+                sum += reader::vuint_at(data, i).unwrap().val;
                 i += 4;
             }
         });
@@ -1071,7 +1130,7 @@ mod bench {
         bh.iter(|| {
             let mut i = 1;
             while i < data.len() {
-                sum += reader::vuint_at(data, i).val;
+                sum += reader::vuint_at(data, i).unwrap().val;
                 i += 4;
             }
         });
@@ -1091,7 +1150,7 @@ mod bench {
         bh.iter(|| {
             let mut i = 0;
             while i < data.len() {
-                sum += reader::vuint_at(data, i).val;
+                sum += reader::vuint_at(data, i).unwrap().val;
                 i += 4;
             }
         });
@@ -1111,7 +1170,7 @@ mod bench {
         bh.iter(|| {
             let mut i = 1;
             while i < data.len() {
-                sum += reader::vuint_at(data, i).val;
+                sum += reader::vuint_at(data, i).unwrap().val;
                 i += 4;
             }
         });
diff --git a/src/libserialize/ebml_old.rs b/src/libserialize/ebml_old.rs
new file mode 100644
index 00000000000..1c66960672f
--- /dev/null
+++ b/src/libserialize/ebml_old.rs
@@ -0,0 +1,1120 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[allow(missing_doc)];
+
+use std::str;
+
+macro_rules! try( ($e:expr) => (
+    match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } }
+) )
+
+// Simple Extensible Binary Markup Language (ebml) reader and writer on a
+// cursor model. See the specification here:
+//     http://www.matroska.org/technical/specs/rfc/index.html
+
+// Common data structures
+#[deriving(Clone)]
+pub struct Doc<'a> {
+    data: &'a [u8],
+    start: uint,
+    end: uint,
+}
+
+impl<'doc> Doc<'doc> {
+    pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
+        reader::get_doc(*self, tag)
+    }
+
+    pub fn as_str_slice<'a>(&'a self) -> &'a str {
+        str::from_utf8(self.data.slice(self.start, self.end)).unwrap()
+    }
+
+    pub fn as_str(&self) -> ~str {
+        self.as_str_slice().to_owned()
+    }
+}
+
+pub struct TaggedDoc<'a> {
+    priv tag: uint,
+    doc: Doc<'a>,
+}
+
+pub enum EbmlEncoderTag {
+    EsUint,     // 0
+    EsU64,      // 1
+    EsU32,      // 2
+    EsU16,      // 3
+    EsU8,       // 4
+    EsInt,      // 5
+    EsI64,      // 6
+    EsI32,      // 7
+    EsI16,      // 8
+    EsI8,       // 9
+    EsBool,     // 10
+    EsChar,     // 11
+    EsStr,      // 12
+    EsF64,      // 13
+    EsF32,      // 14
+    EsFloat,    // 15
+    EsEnum,     // 16
+    EsEnumVid,  // 17
+    EsEnumBody, // 18
+    EsVec,      // 19
+    EsVecLen,   // 20
+    EsVecElt,   // 21
+    EsMap,      // 22
+    EsMapLen,   // 23
+    EsMapKey,   // 24
+    EsMapVal,   // 25
+
+    EsOpaque,
+
+    EsLabel, // Used only when debugging
+}
+// --------------------------------------
+
+pub mod reader {
+    use std::char;
+
+    use std::cast::transmute;
+    use std::int;
+    use std::option::{None, Option, Some};
+    use std::io::extensions::u64_from_be_bytes;
+
+    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 };
+
+    // ebml reading
+
+    pub struct Res {
+        val: uint,
+        next: uint
+    }
+
+    #[inline(never)]
+    fn vuint_at_slow(data: &[u8], start: uint) -> Res {
+        let a = data[start];
+        if a & 0x80u8 != 0u8 {
+            return Res {val: (a & 0x7fu8) as uint, next: start + 1u};
+        }
+        if a & 0x40u8 != 0u8 {
+            return Res {val: ((a & 0x3fu8) as uint) << 8u |
+                        (data[start + 1u] as uint),
+                    next: start + 2u};
+        }
+        if a & 0x20u8 != 0u8 {
+            return Res {val: ((a & 0x1fu8) as uint) << 16u |
+                        (data[start + 1u] as uint) << 8u |
+                        (data[start + 2u] as uint),
+                    next: start + 3u};
+        }
+        if a & 0x10u8 != 0u8 {
+            return Res {val: ((a & 0x0fu8) as uint) << 24u |
+                        (data[start + 1u] as uint) << 16u |
+                        (data[start + 2u] as uint) << 8u |
+                        (data[start + 3u] as uint),
+                    next: start + 4u};
+        }
+        fail!("vint too big");
+    }
+
+    pub fn vuint_at(data: &[u8], start: uint) -> Res {
+        use std::mem::from_be32;
+
+        if data.len() - start < 4 {
+            return vuint_at_slow(data, start);
+        }
+
+        // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
+        // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
+        // Using the four most significant bits of the u32 we lookup in the table below how the
+        // element ID should be derived from it.
+        //
+        // The table stores tuples (shift, mask) where shift is the number the u32 should be right
+        // shifted with and mask is the value the right shifted value should be masked with.
+        // If for example the most significant bit is set this means it's a class A ID and the u32
+        // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
+        // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
+        //
+        // By storing the number of shifts and masks in a table instead of checking in order if
+        // the most significant bit is set, the second most significant bit is set etc. we can
+        // replace up to three "and+branch" with a single table lookup which gives us a measured
+        // speedup of around 2x on x86_64.
+        static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [
+            (0, 0x0), (0, 0x0fffffff),
+            (8, 0x1fffff), (8, 0x1fffff),
+            (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
+            (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
+            (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
+        ];
+
+        unsafe {
+            let ptr = data.as_ptr().offset(start as int) as *i32;
+            let val = from_be32(*ptr) as u32;
+
+            let i = (val >> 28u) as uint;
+            let (shift, mask) = SHIFT_MASK_TABLE[i];
+            Res {
+                val: ((val >> shift) & mask) as uint,
+                next: start + (((32 - shift) >> 3) as uint)
+            }
+        }
+    }
+
+    pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> {
+        Doc { data: data, start: 0u, end: data.len() }
+    }
+
+    pub fn doc_at<'a>(data: &'a [u8], start: uint) -> TaggedDoc<'a> {
+        let elt_tag = vuint_at(data, start);
+        let elt_size = vuint_at(data, elt_tag.next);
+        let end = elt_size.next + elt_size.val;
+        TaggedDoc {
+            tag: elt_tag.val,
+            doc: Doc { data: data, start: elt_size.next, end: end }
+        }
+    }
+
+    pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
+        let mut pos = d.start;
+        while pos < d.end {
+            let elt_tag = vuint_at(d.data, pos);
+            let elt_size = vuint_at(d.data, elt_tag.next);
+            pos = elt_size.next + elt_size.val;
+            if elt_tag.val == tg {
+                return Some(Doc { data: d.data, start: elt_size.next,
+                                  end: pos });
+            }
+        }
+        None
+    }
+
+    pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
+        match maybe_get_doc(d, tg) {
+            Some(d) => d,
+            None => {
+                error!("failed to find block with tag {}", tg);
+                fail!();
+            }
+        }
+    }
+
+    pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
+        let mut pos = d.start;
+        while pos < d.end {
+            let elt_tag = vuint_at(d.data, pos);
+            let elt_size = vuint_at(d.data, elt_tag.next);
+            pos = elt_size.next + elt_size.val;
+            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+            if !it(elt_tag.val, doc) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
+        let mut pos = d.start;
+        while pos < d.end {
+            let elt_tag = vuint_at(d.data, pos);
+            let elt_size = vuint_at(d.data, elt_tag.next);
+            pos = elt_size.next + elt_size.val;
+            if elt_tag.val == tg {
+                let doc = Doc { data: d.data, start: elt_size.next,
+                                end: pos };
+                if !it(doc) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
+        f(d.data.slice(d.start, d.end))
+    }
+
+
+    pub fn doc_as_u8(d: Doc) -> u8 {
+        assert_eq!(d.end, d.start + 1u);
+        d.data[d.start]
+    }
+
+    pub fn doc_as_u16(d: Doc) -> u16 {
+        assert_eq!(d.end, d.start + 2u);
+        u64_from_be_bytes(d.data, d.start, 2u) as u16
+    }
+
+    pub fn doc_as_u32(d: Doc) -> u32 {
+        assert_eq!(d.end, d.start + 4u);
+        u64_from_be_bytes(d.data, d.start, 4u) as u32
+    }
+
+    pub fn doc_as_u64(d: Doc) -> u64 {
+        assert_eq!(d.end, d.start + 8u);
+        u64_from_be_bytes(d.data, d.start, 8u)
+    }
+
+    pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
+    pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
+    pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
+    pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
+
+    pub struct Decoder<'a> {
+        priv parent: Doc<'a>,
+        priv pos: uint,
+    }
+
+    pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
+        Decoder {
+            parent: d,
+            pos: d.start
+        }
+    }
+
+    impl<'doc> Decoder<'doc> {
+        fn _check_label(&mut self, lbl: &str) {
+            if self.pos < self.parent.end {
+                let TaggedDoc { tag: r_tag, doc: r_doc } =
+                    doc_at(self.parent.data, self.pos);
+
+                if r_tag == (EsLabel as uint) {
+                    self.pos = r_doc.end;
+                    let str = r_doc.as_str_slice();
+                    if lbl != str {
+                        fail!("Expected label {} but found {}", lbl, str);
+                    }
+                }
+            }
+        }
+
+        fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc<'doc> {
+            debug!(". next_doc(exp_tag={:?})", exp_tag);
+            if self.pos >= self.parent.end {
+                fail!("no more documents in current node!");
+            }
+            let TaggedDoc { tag: r_tag, doc: r_doc } =
+                doc_at(self.parent.data, self.pos);
+            debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
+                   self.parent.start,
+                   self.parent.end,
+                   self.pos,
+                   r_tag,
+                   r_doc.start,
+                   r_doc.end);
+            if r_tag != (exp_tag as uint) {
+                fail!("expected EBML doc with tag {:?} but found tag {:?}",
+                       exp_tag, r_tag);
+            }
+            if r_doc.end > self.parent.end {
+                fail!("invalid EBML, child extends to {:#x}, parent to {:#x}",
+                      r_doc.end, self.parent.end);
+            }
+            self.pos = r_doc.end;
+            r_doc
+        }
+
+        fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
+                       f: |&mut Decoder<'doc>| -> T) -> T {
+            let d = self.next_doc(exp_tag);
+            let old_parent = self.parent;
+            let old_pos = self.pos;
+            self.parent = d;
+            self.pos = d.start;
+            let r = f(self);
+            self.parent = old_parent;
+            self.pos = old_pos;
+            r
+        }
+
+        fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
+            let r = doc_as_u32(self.next_doc(exp_tag));
+            debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
+            r as uint
+        }
+
+        pub fn read_opaque<R>(&mut self, op: |&mut Decoder<'doc>, Doc| -> R) -> R {
+            let doc = self.next_doc(EsOpaque);
+
+            let (old_parent, old_pos) = (self.parent, self.pos);
+            self.parent = doc;
+            self.pos = doc.start;
+
+            let result = op(self, doc);
+
+            self.parent = old_parent;
+            self.pos = old_pos;
+            result
+        }
+    }
+
+    impl<'doc> serialize::Decoder for Decoder<'doc> {
+        fn read_nil(&mut self) -> () { () }
+
+        fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
+        fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
+        fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
+        fn read_u8 (&mut self) -> u8  { doc_as_u8 (self.next_doc(EsU8 )) }
+        fn read_uint(&mut self) -> uint {
+            let v = doc_as_u64(self.next_doc(EsUint));
+            if v > (::std::uint::MAX as u64) {
+                fail!("uint {} too large for this architecture", v);
+            }
+            v as uint
+        }
+
+        fn read_i64(&mut self) -> i64 {
+            doc_as_u64(self.next_doc(EsI64)) as i64
+        }
+        fn read_i32(&mut self) -> i32 {
+            doc_as_u32(self.next_doc(EsI32)) as i32
+        }
+        fn read_i16(&mut self) -> i16 {
+            doc_as_u16(self.next_doc(EsI16)) as i16
+        }
+        fn read_i8 (&mut self) -> i8 {
+            doc_as_u8(self.next_doc(EsI8 )) as i8
+        }
+        fn read_int(&mut self) -> int {
+            let v = doc_as_u64(self.next_doc(EsInt)) as i64;
+            if v > (int::MAX as i64) || v < (int::MIN as i64) {
+                debug!("FIXME \\#6122: Removing this makes this function miscompile");
+                fail!("int {} out of range for this architecture", v);
+            }
+            v as int
+        }
+
+        fn read_bool(&mut self) -> bool {
+            doc_as_u8(self.next_doc(EsBool)) != 0
+        }
+
+        fn read_f64(&mut self) -> f64 {
+            let bits = doc_as_u64(self.next_doc(EsF64));
+            unsafe { transmute(bits) }
+        }
+        fn read_f32(&mut self) -> f32 {
+            let bits = doc_as_u32(self.next_doc(EsF32));
+            unsafe { transmute(bits) }
+        }
+        fn read_char(&mut self) -> char {
+            char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
+        }
+        fn read_str(&mut self) -> ~str {
+            self.next_doc(EsStr).as_str()
+        }
+
+        // Compound types:
+        fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder<'doc>| -> T) -> T {
+            debug!("read_enum({})", name);
+            self._check_label(name);
+
+            let doc = self.next_doc(EsEnum);
+
+            let (old_parent, old_pos) = (self.parent, self.pos);
+            self.parent = doc;
+            self.pos = self.parent.start;
+
+            let result = f(self);
+
+            self.parent = old_parent;
+            self.pos = old_pos;
+            result
+        }
+
+        fn read_enum_variant<T>(&mut self,
+                                _: &[&str],
+                                f: |&mut Decoder<'doc>, uint| -> T)
+                                -> T {
+            debug!("read_enum_variant()");
+            let idx = self._next_uint(EsEnumVid);
+            debug!("  idx={}", idx);
+
+            let doc = self.next_doc(EsEnumBody);
+
+            let (old_parent, old_pos) = (self.parent, self.pos);
+            self.parent = doc;
+            self.pos = self.parent.start;
+
+            let result = f(self, idx);
+
+            self.parent = old_parent;
+            self.pos = old_pos;
+            result
+        }
+
+        fn read_enum_variant_arg<T>(&mut self,
+                                    idx: uint,
+                                    f: |&mut Decoder<'doc>| -> T) -> T {
+            debug!("read_enum_variant_arg(idx={})", idx);
+            f(self)
+        }
+
+        fn read_enum_struct_variant<T>(&mut self,
+                                       _: &[&str],
+                                       f: |&mut Decoder<'doc>, uint| -> T)
+                                       -> T {
+            debug!("read_enum_struct_variant()");
+            let idx = self._next_uint(EsEnumVid);
+            debug!("  idx={}", idx);
+
+            let doc = self.next_doc(EsEnumBody);
+
+            let (old_parent, old_pos) = (self.parent, self.pos);
+            self.parent = doc;
+            self.pos = self.parent.start;
+
+            let result = f(self, idx);
+
+            self.parent = old_parent;
+            self.pos = old_pos;
+            result
+        }
+
+        fn read_enum_struct_variant_field<T>(&mut self,
+                                             name: &str,
+                                             idx: uint,
+                                             f: |&mut Decoder<'doc>| -> T)
+                                             -> T {
+            debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
+            f(self)
+        }
+
+        fn read_struct<T>(&mut self,
+                          name: &str,
+                          _: uint,
+                          f: |&mut Decoder<'doc>| -> T)
+                          -> T {
+            debug!("read_struct(name={})", name);
+            f(self)
+        }
+
+        fn read_struct_field<T>(&mut self,
+                                name: &str,
+                                idx: uint,
+                                f: |&mut Decoder<'doc>| -> T)
+                                -> T {
+            debug!("read_struct_field(name={}, idx={})", name, idx);
+            self._check_label(name);
+            f(self)
+        }
+
+        fn read_tuple<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+            debug!("read_tuple()");
+            self.read_seq(f)
+        }
+
+        fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
+                             -> 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<'doc>, uint| -> T)
+                                -> T {
+            debug!("read_tuple_struct(name={})", name);
+            self.read_tuple(f)
+        }
+
+        fn read_tuple_struct_arg<T>(&mut self,
+                                    idx: uint,
+                                    f: |&mut Decoder<'doc>| -> T)
+                                    -> T {
+            debug!("read_tuple_struct_arg(idx={})", idx);
+            self.read_tuple_arg(idx, f)
+        }
+
+        fn read_option<T>(&mut self, f: |&mut Decoder<'doc>, bool| -> T) -> T {
+            debug!("read_option()");
+            self.read_enum("Option", |this| {
+                this.read_enum_variant(["None", "Some"], |this, idx| {
+                    match idx {
+                        0 => f(this, false),
+                        1 => f(this, true),
+                        _ => fail!(),
+                    }
+                })
+            })
+        }
+
+        fn read_seq<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+            debug!("read_seq()");
+            self.push_doc(EsVec, |d| {
+                let len = d._next_uint(EsVecLen);
+                debug!("  len={}", len);
+                f(d, len)
+            })
+        }
+
+        fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
+                           -> T {
+            debug!("read_seq_elt(idx={})", idx);
+            self.push_doc(EsVecElt, f)
+        }
+
+        fn read_map<T>(&mut self, f: |&mut Decoder<'doc>, uint| -> T) -> T {
+            debug!("read_map()");
+            self.push_doc(EsMap, |d| {
+                let len = d._next_uint(EsMapLen);
+                debug!("  len={}", len);
+                f(d, len)
+            })
+        }
+
+        fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
+                               -> T {
+            debug!("read_map_elt_key(idx={})", idx);
+            self.push_doc(EsMapKey, f)
+        }
+
+        fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> T)
+                               -> T {
+            debug!("read_map_elt_val(idx={})", idx);
+            self.push_doc(EsMapVal, f)
+        }
+    }
+}
+
+pub mod writer {
+    use std::cast;
+    use std::clone::Clone;
+    use std::io;
+    use std::io::{Writer, Seek};
+    use std::io::MemWriter;
+    use std::io::extensions::u64_to_be_bytes;
+
+    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 };
+
+    use serialize;
+
+    // ebml writing
+    pub struct Encoder<'a> {
+        // FIXME(#5665): this should take a trait object. Note that if you
+        //               delete this comment you should consider removing the
+        //               unwrap()'s below of the results of the calls to
+        //               write(). We're guaranteed that writing into a MemWriter
+        //               won't fail, but this is not true for all I/O streams in
+        //               general.
+        writer: &'a mut MemWriter,
+        priv size_positions: ~[uint],
+        last_error: io::IoResult<()>,
+    }
+
+    fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
+        match size {
+            1u => w.write(&[0x80u8 | (n as u8)]),
+            2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
+            3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
+                            n as u8]),
+            4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
+                            (n >> 8_u) as u8, n as u8]),
+            _ => fail!("vint to write too big: {}", n)
+        }.unwrap()
+    }
+
+    fn write_vuint(w: &mut MemWriter, n: uint) {
+        if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
+        if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
+        if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
+        if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
+        fail!("vint to write too big: {}", n);
+    }
+
+    pub fn Encoder<'a>(w: &'a mut MemWriter) -> Encoder<'a> {
+        let size_positions: ~[uint] = ~[];
+        Encoder {
+            writer: w,
+            size_positions: size_positions,
+            last_error: Ok(()),
+        }
+    }
+
+    // FIXME (#2741): Provide a function to write the standard ebml header.
+    impl<'a> Encoder<'a> {
+        /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
+        pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
+            Encoder {
+                writer: cast::transmute_copy(&self.writer),
+                size_positions: self.size_positions.clone(),
+                last_error: Ok(()),
+            }
+        }
+
+        pub fn start_tag(&mut self, tag_id: uint) {
+            debug!("Start tag {}", tag_id);
+
+            // Write the enum ID:
+            write_vuint(self.writer, tag_id);
+
+            // Write a placeholder four-byte size.
+            self.size_positions.push(try!(self.writer.tell()) as uint);
+            let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
+            try!(self.writer.write(zeroes));
+        }
+
+        pub fn end_tag(&mut self) {
+            let last_size_pos = self.size_positions.pop().unwrap();
+            let cur_pos = try!(self.writer.tell());
+            try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
+            let size = cur_pos as uint - last_size_pos - 4;
+            write_sized_vuint(self.writer, size, 4u);
+            try!(self.writer.seek(cur_pos as i64, io::SeekSet));
+
+            debug!("End tag (size = {})", size);
+        }
+
+        pub fn wr_tag(&mut self, tag_id: uint, blk: ||) {
+            self.start_tag(tag_id);
+            blk();
+            self.end_tag();
+        }
+
+        pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
+            write_vuint(self.writer, tag_id);
+            write_vuint(self.writer, b.len());
+            self.writer.write(b).unwrap();
+        }
+
+        pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
+            u64_to_be_bytes(v, 8u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) {
+            u64_to_be_bytes(v as u64, 4u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) {
+            u64_to_be_bytes(v as u64, 2u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) {
+            self.wr_tagged_bytes(tag_id, &[v]);
+        }
+
+        pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) {
+            u64_to_be_bytes(v as u64, 8u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) {
+            u64_to_be_bytes(v as u64, 4u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) {
+            u64_to_be_bytes(v as u64, 2u, |v| {
+                self.wr_tagged_bytes(tag_id, v);
+            })
+        }
+
+        pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) {
+            self.wr_tagged_bytes(tag_id, &[v as u8]);
+        }
+
+        pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
+            self.wr_tagged_bytes(tag_id, v.as_bytes());
+        }
+
+        pub fn wr_bytes(&mut self, b: &[u8]) {
+            debug!("Write {} bytes", b.len());
+            self.writer.write(b).unwrap();
+        }
+
+        pub fn wr_str(&mut self, s: &str) {
+            debug!("Write str: {}", s);
+            self.writer.write(s.as_bytes()).unwrap();
+        }
+    }
+
+    // FIXME (#2743): optionally perform "relaxations" on end_tag to more
+    // efficiently encode sizes; this is a fixed point iteration
+
+    // Set to true to generate more debugging in EBML code.
+    // Totally lame approach.
+    static DEBUG: bool = true;
+
+    impl<'a> Encoder<'a> {
+        // used internally to emit things like the vector length and so on
+        fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
+            assert!(v <= 0xFFFF_FFFF_u);
+            self.wr_tagged_u32(t as uint, v as u32);
+        }
+
+        fn _emit_label(&mut self, label: &str) {
+            // There are various strings that we have access to, such as
+            // the name of a record field, which do not actually appear in
+            // the encoded EBML (normally).  This is just for
+            // efficiency.  When debugging, though, we can emit such
+            // labels and then they will be checked by decoder to
+            // try and check failures more quickly.
+            if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
+        }
+
+        pub fn emit_opaque(&mut self, f: |&mut Encoder|) {
+            self.start_tag(EsOpaque as uint);
+            f(self);
+            self.end_tag();
+        }
+    }
+
+    impl<'a> serialize::Encoder for Encoder<'a> {
+        fn emit_nil(&mut self) {}
+
+        fn emit_uint(&mut self, v: uint) {
+            self.wr_tagged_u64(EsUint as uint, v as u64);
+        }
+        fn emit_u64(&mut self, v: u64) {
+            self.wr_tagged_u64(EsU64 as uint, v);
+        }
+        fn emit_u32(&mut self, v: u32) {
+            self.wr_tagged_u32(EsU32 as uint, v);
+        }
+        fn emit_u16(&mut self, v: u16) {
+            self.wr_tagged_u16(EsU16 as uint, v);
+        }
+        fn emit_u8(&mut self, v: u8) {
+            self.wr_tagged_u8(EsU8 as uint, v);
+        }
+
+        fn emit_int(&mut self, v: int) {
+            self.wr_tagged_i64(EsInt as uint, v as i64);
+        }
+        fn emit_i64(&mut self, v: i64) {
+            self.wr_tagged_i64(EsI64 as uint, v);
+        }
+        fn emit_i32(&mut self, v: i32) {
+            self.wr_tagged_i32(EsI32 as uint, v);
+        }
+        fn emit_i16(&mut self, v: i16) {
+            self.wr_tagged_i16(EsI16 as uint, v);
+        }
+        fn emit_i8(&mut self, v: i8) {
+            self.wr_tagged_i8(EsI8 as uint, v);
+        }
+
+        fn emit_bool(&mut self, v: bool) {
+            self.wr_tagged_u8(EsBool as uint, v as u8)
+        }
+
+        fn emit_f64(&mut self, v: f64) {
+            let bits = unsafe { cast::transmute(v) };
+            self.wr_tagged_u64(EsF64 as uint, bits);
+        }
+        fn emit_f32(&mut self, v: f32) {
+            let bits = unsafe { cast::transmute(v) };
+            self.wr_tagged_u32(EsF32 as uint, bits);
+        }
+        fn emit_char(&mut self, v: char) {
+            self.wr_tagged_u32(EsChar as uint, v as u32);
+        }
+
+        fn emit_str(&mut self, v: &str) {
+            self.wr_tagged_str(EsStr as uint, v)
+        }
+
+        fn emit_enum(&mut self, name: &str, f: |&mut Encoder<'a>|) {
+            self._emit_label(name);
+            self.start_tag(EsEnum as uint);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_enum_variant(&mut self,
+                             _: &str,
+                             v_id: uint,
+                             _: uint,
+                             f: |&mut Encoder<'a>|) {
+            self._emit_tagged_uint(EsEnumVid, v_id);
+            self.start_tag(EsEnumBody as uint);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_enum_variant_arg(&mut self, _: uint, f: |&mut Encoder<'a>|) {
+            f(self)
+        }
+
+        fn emit_enum_struct_variant(&mut self,
+                                    v_name: &str,
+                                    v_id: uint,
+                                    cnt: uint,
+                                    f: |&mut Encoder<'a>|) {
+            self.emit_enum_variant(v_name, v_id, cnt, f)
+        }
+
+        fn emit_enum_struct_variant_field(&mut self,
+                                          _: &str,
+                                          idx: uint,
+                                          f: |&mut Encoder<'a>|) {
+            self.emit_enum_variant_arg(idx, f)
+        }
+
+        fn emit_struct(&mut self,
+                       _: &str,
+                       _len: uint,
+                       f: |&mut Encoder<'a>|) {
+            f(self)
+        }
+
+        fn emit_struct_field(&mut self,
+                             name: &str,
+                             _: uint,
+                             f: |&mut Encoder<'a>|) {
+            self._emit_label(name);
+            f(self)
+        }
+
+        fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) {
+            self.emit_seq(len, f)
+        }
+        fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+            self.emit_seq_elt(idx, f)
+        }
+
+        fn emit_tuple_struct(&mut self,
+                             _: &str,
+                             len: uint,
+                             f: |&mut Encoder<'a>|) {
+            self.emit_seq(len, f)
+        }
+        fn emit_tuple_struct_arg(&mut self,
+                                 idx: uint,
+                                 f: |&mut Encoder<'a>|) {
+            self.emit_seq_elt(idx, f)
+        }
+
+        fn emit_option(&mut self, f: |&mut Encoder<'a>|) {
+            self.emit_enum("Option", f);
+        }
+        fn emit_option_none(&mut self) {
+            self.emit_enum_variant("None", 0, 0, |_| ())
+        }
+        fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) {
+            self.emit_enum_variant("Some", 1, 1, f)
+        }
+
+        fn emit_seq(&mut self, len: uint, f: |&mut Encoder<'a>|) {
+            self.start_tag(EsVec as uint);
+            self._emit_tagged_uint(EsVecLen, len);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_seq_elt(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
+            self.start_tag(EsVecElt as uint);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_map(&mut self, len: uint, f: |&mut Encoder<'a>|) {
+            self.start_tag(EsMap as uint);
+            self._emit_tagged_uint(EsMapLen, len);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_map_elt_key(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
+            self.start_tag(EsMapKey as uint);
+            f(self);
+            self.end_tag();
+        }
+
+        fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
+            self.start_tag(EsMapVal as uint);
+            f(self);
+            self.end_tag();
+        }
+    }
+}
+
+// ___________________________________________________________________________
+// Testing
+
+#[cfg(test)]
+mod tests {
+    use ebml::reader;
+    use ebml::writer;
+    use {Encodable, Decodable};
+
+    use std::io::MemWriter;
+    use std::option::{None, Option, Some};
+
+    #[test]
+    fn test_vuint_at() {
+        let data = [
+            0x80,
+            0xff,
+            0x40, 0x00,
+            0x7f, 0xff,
+            0x20, 0x00, 0x00,
+            0x3f, 0xff, 0xff,
+            0x10, 0x00, 0x00, 0x00,
+            0x1f, 0xff, 0xff, 0xff
+        ];
+
+        let mut res: reader::Res;
+
+        // Class A
+        res = reader::vuint_at(data, 0);
+        assert_eq!(res.val, 0);
+        assert_eq!(res.next, 1);
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, (1 << 7) - 1);
+        assert_eq!(res.next, 2);
+
+        // Class B
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, 0);
+        assert_eq!(res.next, 4);
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, (1 << 14) - 1);
+        assert_eq!(res.next, 6);
+
+        // Class C
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, 0);
+        assert_eq!(res.next, 9);
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, (1 << 21) - 1);
+        assert_eq!(res.next, 12);
+
+        // Class D
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, 0);
+        assert_eq!(res.next, 16);
+        res = reader::vuint_at(data, res.next);
+        assert_eq!(res.val, (1 << 28) - 1);
+        assert_eq!(res.next, 20);
+    }
+
+    #[test]
+    fn test_option_int() {
+        fn test_v(v: Option<int>) {
+            debug!("v == {:?}", v);
+            let mut wr = MemWriter::new();
+            {
+                let mut ebml_w = writer::Encoder(&mut wr);
+                v.encode(&mut ebml_w);
+            }
+            let ebml_doc = reader::Doc(wr.get_ref());
+            let mut deser = reader::Decoder(ebml_doc);
+            let v1 = Decodable::decode(&mut deser);
+            debug!("v1 == {:?}", v1);
+            assert_eq!(v, v1);
+        }
+
+        test_v(Some(22));
+        test_v(None);
+        test_v(Some(3));
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use ebml::reader;
+
+    #[bench]
+    pub fn vuint_at_A_aligned(bh: &mut BenchHarness) {
+        use std::slice;
+        let data = slice::from_fn(4*100, |i| {
+            match i % 2 {
+              0 => 0x80u8,
+              _ => i as u8,
+            }
+        });
+        let mut sum = 0u;
+        bh.iter(|| {
+            let mut i = 0;
+            while i < data.len() {
+                sum += reader::vuint_at(data, i).val;
+                i += 4;
+            }
+        });
+    }
+
+    #[bench]
+    pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) {
+        use std::slice;
+        let data = slice::from_fn(4*100+1, |i| {
+            match i % 2 {
+              1 => 0x80u8,
+              _ => i as u8
+            }
+        });
+        let mut sum = 0u;
+        bh.iter(|| {
+            let mut i = 1;
+            while i < data.len() {
+                sum += reader::vuint_at(data, i).val;
+                i += 4;
+            }
+        });
+    }
+
+    #[bench]
+    pub fn vuint_at_D_aligned(bh: &mut BenchHarness) {
+        use std::slice;
+        let data = slice::from_fn(4*100, |i| {
+            match i % 4 {
+              0 => 0x10u8,
+              3 => i as u8,
+              _ => 0u8
+            }
+        });
+        let mut sum = 0u;
+        bh.iter(|| {
+            let mut i = 0;
+            while i < data.len() {
+                sum += reader::vuint_at(data, i).val;
+                i += 4;
+            }
+        });
+    }
+
+    #[bench]
+    pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) {
+        use std::slice;
+        let data = slice::from_fn(4*100+1, |i| {
+            match i % 4 {
+              1 => 0x10u8,
+              0 => i as u8,
+              _ => 0u8
+            }
+        });
+        let mut sum = 0u;
+        bh.iter(|| {
+            let mut i = 1;
+            while i < data.len() {
+                sum += reader::vuint_at(data, i).val;
+                i += 4;
+            }
+        });
+    }
+}
+
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();
     }
 }
diff --git a/src/libserialize/json_old.rs b/src/libserialize/json_old.rs
new file mode 100644
index 00000000000..cc4c86599fa
--- /dev/null
+++ b/src/libserialize/json_old.rs
@@ -0,0 +1,2606 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Rust JSON serialization library
+// Copyright (c) 2011 Google Inc.
+
+#[forbid(non_camel_case_types)];
+#[allow(missing_doc)];
+
+/*!
+JSON parsing and serialization
+
+# What is JSON?
+
+JSON (JavaScript Object Notation) is a way to write data in Javascript.
+Like XML it allows one to encode structured data in a text format that can be read by humans easily.
+Its native compatibility with JavaScript and its simple syntax make it used widely.
+
+Json data are encoded in a form of "key":"value".
+Data types that can be encoded are JavaScript types :
+boolean (`true` or `false`), number (`f64`), string, array, object, null.
+An object is a series of string keys mapping to values, in `"key": value` format.
+Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).
+A simple JSON document encoding a person, his/her age, address and phone numbers could look like:
+
+```ignore
+{
+    "FirstName": "John",
+    "LastName": "Doe",
+    "Age": 43,
+    "Address": {
+        "Street": "Downing Street 10",
+        "City": "London",
+        "Country": "Great Britain"
+    },
+    "PhoneNumbers": [
+        "+44 1234567",
+        "+44 2345678"
+    ]
+}
+```
+
+# Rust Type-based Encoding and Decoding
+
+Rust provides a mechanism for low boilerplate encoding & decoding
+of values to and from JSON via the serialization API.
+To be able to encode a piece of data, it must implement the `serialize::Encodable` trait.
+To be able to decode a piece of data, it must implement the `serialize::Decodable` trait.
+The Rust compiler provides an annotation to automatically generate
+the code for these traits: `#[deriving(Decodable, Encodable)]`
+
+To encode using Encodable :
+
+```rust
+use std::io;
+use serialize::{json, Encodable};
+
+ #[deriving(Encodable)]
+ pub struct TestStruct   {
+    data_str: ~str,
+ }
+
+fn main() {
+    let to_encode_object = TestStruct{data_str:~"example of string to encode"};
+    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);
+    }
+}
+```
+
+Two wrapper functions are provided to encode a Encodable object
+into a string (~str) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m)`.
+
+```rust
+use serialize::json;
+let to_encode_object = ~"example of string to encode";
+let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object);
+```
+
+JSON API provide an enum `json::Json` and a trait `ToJson` to encode object.
+The trait `ToJson` encode object into a container `json::Json` and the API provide writer
+to encode them into a stream or a string ...
+
+When using `ToJson` the `Encodable` trait implementation is not mandatory.
+
+A basic `ToJson` example using a TreeMap of attribute name / attribute value:
+
+
+```rust
+extern crate collections;
+extern crate serialize;
+
+use serialize::json;
+use serialize::json::ToJson;
+use collections::TreeMap;
+
+pub struct MyStruct  {
+    attr1: u8,
+    attr2: ~str,
+}
+
+impl ToJson for MyStruct {
+    fn to_json( &self ) -> json::Json {
+        let mut d = ~TreeMap::new();
+        d.insert(~"attr1", self.attr1.to_json());
+        d.insert(~"attr2", self.attr2.to_json());
+        json::Object(d)
+    }
+}
+
+fn main() {
+    let test2: MyStruct = MyStruct {attr1: 1, attr2:~"test"};
+    let tjson: json::Json = test2.to_json();
+    let json_str: ~str = tjson.to_str();
+}
+```
+
+To decode a JSON string using `Decodable` trait :
+
+```rust
+extern crate serialize;
+use serialize::{json, Decodable};
+
+#[deriving(Decodable)]
+pub struct MyStruct  {
+     attr1: u8,
+     attr2: ~str,
+}
+
+fn main() {
+    let json_str_to_decode: ~str =
+            ~"{\"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
+}
+```
+
+# Examples of use
+
+## Using Autoserialization
+
+Create a struct called TestStruct1 and serialize and deserialize it to and from JSON
+using the serialization API, using the derived serialization code.
+
+```rust
+extern crate serialize;
+use serialize::{json, Encodable, Decodable};
+
+ #[deriving(Decodable, Encodable)] //generate Decodable, Encodable impl.
+ pub struct TestStruct1  {
+    data_int: u8,
+    data_str: ~str,
+    data_vector: ~[u8],
+ }
+
+// To serialize use the `json::str_encode` to encode an object in a string.
+// It calls the generated `Encodable` impl.
+fn main() {
+    let to_encode_object = TestStruct1
+         {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]};
+    let encoded_str: ~str = json::Encoder::str_encode(&to_encode_object);
+
+    // To deserialize use the `json::from_str` and `json::Decoder`
+
+    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
+}
+```
+
+## Using `ToJson`
+
+This example use the ToJson impl to deserialize the JSON string.
+Example of `ToJson` trait implementation for TestStruct1.
+
+```rust
+extern crate serialize;
+extern crate collections;
+
+use serialize::json::ToJson;
+use serialize::{json, Encodable, Decodable};
+use collections::TreeMap;
+
+#[deriving(Decodable, Encodable)] // generate Decodable, Encodable impl.
+pub struct TestStruct1  {
+    data_int: u8,
+    data_str: ~str,
+    data_vector: ~[u8],
+}
+
+impl ToJson for TestStruct1 {
+    fn to_json( &self ) -> json::Json {
+        let mut d = ~TreeMap::new();
+        d.insert(~"data_int", self.data_int.to_json());
+        d.insert(~"data_str", self.data_str.to_json());
+        d.insert(~"data_vector", self.data_vector.to_json());
+        json::Object(d)
+    }
+}
+
+fn main() {
+    // Serialization using our impl of to_json
+
+    let test2: TestStruct1 = TestStruct1 {data_int: 1, data_str:~"toto", data_vector:~[2,3,4,5]};
+    let tjson: json::Json = test2.to_json();
+    let json_str: ~str = tjson.to_str();
+
+    // Deserialize like before.
+
+    let mut decoder = json::Decoder::new(json::from_str(json_str).unwrap());
+    // create the final object
+    let decoded2: TestStruct1 = Decodable::decode(&mut decoder);
+}
+```
+
+*/
+
+use std::char;
+use std::f64;
+use collections::HashMap;
+use std::io;
+use std::io::MemWriter;
+use std::num;
+use std::str;
+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 {
+    Number(f64),
+    String(~str),
+    Boolean(bool),
+    List(List),
+    Object(~Object),
+    Null,
+}
+
+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,
+}
+
+fn io_error_to_error(io: io::IoError) -> Error {
+    Error {
+        line: 0,
+        col: 0,
+        msg: format!("io error: {}", io)
+    }
+}
+
+fn escape_str(s: &str) -> ~str {
+    let mut escaped = ~"\"";
+    for c in s.chars() {
+        match c {
+          '"' => escaped.push_str("\\\""),
+          '\\' => escaped.push_str("\\\\"),
+          '\x08' => escaped.push_str("\\b"),
+          '\x0c' => escaped.push_str("\\f"),
+          '\n' => escaped.push_str("\\n"),
+          '\r' => escaped.push_str("\\r"),
+          '\t' => escaped.push_str("\\t"),
+          _ => escaped.push_char(c),
+        }
+    };
+
+    escaped.push_char('"');
+
+    escaped
+}
+
+fn spaces(n: uint) -> ~str {
+    let mut ss = ~"";
+    for _ in range(0, n) { ss.push_str(" "); }
+    return ss;
+}
+
+/// 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(()) }
+    }
+
+    /// Encode the specified struct into a json [u8]
+    pub fn buffer_encode<T:Encodable<Encoder<'a>>>(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);
+        }
+        m.unwrap()
+    }
+
+    /// Encode the specified struct into a json str
+    pub fn str_encode<T:Encodable<Encoder<'a>>>(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")) }
+
+    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_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_bool(&mut self, v: bool) {
+        if v {
+            try!(write!(self.wr, "true"));
+        } else {
+            try!(write!(self.wr, "false"));
+        }
+    }
+
+    fn emit_f64(&mut self, v: f64) {
+        try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)))
+    }
+    fn emit_f32(&mut self, v: f32) { 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_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) }
+
+    fn emit_enum_variant(&mut self,
+                         name: &str,
+                         _id: uint,
+                         cnt: uint,
+                         f: |&mut Encoder<'a>|) {
+        // 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)));
+        } else {
+            try!(write!(self.wr, "\\{\"variant\":"));
+            try!(write!(self.wr, "{}", escape_str(name)));
+            try!(write!(self.wr, ",\"fields\":["));
+            f(self);
+            try!(write!(self.wr, "]\\}"));
+        }
+    }
+
+    fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+        if idx != 0 {
+            try!(write!(self.wr, ","));
+        }
+        f(self);
+    }
+
+    fn emit_enum_struct_variant(&mut self,
+                                name: &str,
+                                id: uint,
+                                cnt: uint,
+                                f: |&mut Encoder<'a>|) {
+        self.emit_enum_variant(name, id, cnt, f)
+    }
+
+    fn emit_enum_struct_variant_field(&mut self,
+                                      _: &str,
+                                      idx: uint,
+                                      f: |&mut Encoder<'a>|) {
+        self.emit_enum_variant_arg(idx, f)
+    }
+
+    fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) {
+        try!(write!(self.wr, r"\{"));
+        f(self);
+        try!(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, ",")) }
+        try!(write!(self.wr, "{}:", escape_str(name)));
+        f(self);
+    }
+
+    fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'a>|) {
+        self.emit_seq(len, f)
+    }
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+        self.emit_seq_elt(idx, f)
+    }
+
+    fn emit_tuple_struct(&mut self,
+                         _name: &str,
+                         len: uint,
+                         f: |&mut Encoder<'a>|) {
+        self.emit_seq(len, f)
+    }
+    fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+        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_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
+        try!(write!(self.wr, "["));
+        f(self);
+        try!(write!(self.wr, "]"));
+    }
+
+    fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+        if idx != 0 {
+            try!(write!(self.wr, ","));
+        }
+        f(self)
+    }
+
+    fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
+        try!(write!(self.wr, r"\{"));
+        f(self);
+        try!(write!(self.wr, r"\}"));
+    }
+
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
+        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);
+        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);
+        if needs_wrapping { try!(write!(self.wr, "\"")); }
+    }
+
+    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
+        try!(write!(self.wr, ":"));
+        f(self)
+    }
+}
+
+/// Another encoder for JSON, but prints out human-readable JSON instead of
+/// compact data
+pub struct PrettyEncoder<'a> {
+    priv wr: &'a mut io::Writer,
+    priv indent: uint,
+    priv error: io::IoResult<()>,
+}
+
+impl<'a> PrettyEncoder<'a> {
+    /// Creates a new encoder whose output will be written to the specified writer
+    pub fn new<'a>(wr: &'a mut io::Writer) -> 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")); }
+
+    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_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_bool(&mut self, v: bool) {
+        if v {
+            try!(write!(self.wr, "true"));
+        } else {
+            try!(write!(self.wr, "false"));
+        }
+    }
+
+    fn emit_f64(&mut self, v: f64) {
+        try!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)));
+    }
+    fn emit_f32(&mut self, v: f32) { 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_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) {
+        f(self)
+    }
+
+    fn emit_enum_variant(&mut self,
+                         name: &str,
+                         _: uint,
+                         cnt: uint,
+                         f: |&mut PrettyEncoder<'a>|) {
+        if cnt == 0 {
+            try!(write!(self.wr, "{}", escape_str(name)));
+        } else {
+            self.indent += 2;
+            try!(write!(self.wr, "[\n{}{},\n", spaces(self.indent),
+                          escape_str(name)));
+            f(self);
+            self.indent -= 2;
+            try!(write!(self.wr, "\n{}]", spaces(self.indent)));
+        }
+    }
+
+    fn emit_enum_variant_arg(&mut self,
+                             idx: uint,
+                             f: |&mut PrettyEncoder<'a>|) {
+        if idx != 0 {
+            try!(write!(self.wr, ",\n"));
+        }
+        try!(write!(self.wr, "{}", spaces(self.indent)));
+        f(self)
+    }
+
+    fn emit_enum_struct_variant(&mut self,
+                                name: &str,
+                                id: uint,
+                                cnt: uint,
+                                f: |&mut PrettyEncoder<'a>|) {
+        self.emit_enum_variant(name, id, cnt, f)
+    }
+
+    fn emit_enum_struct_variant_field(&mut self,
+                                      _: &str,
+                                      idx: uint,
+                                      f: |&mut PrettyEncoder<'a>|) {
+        self.emit_enum_variant_arg(idx, f)
+    }
+
+
+    fn emit_struct(&mut self,
+                   _: &str,
+                   len: uint,
+                   f: |&mut PrettyEncoder<'a>|) {
+        if len == 0 {
+            try!(write!(self.wr, "\\{\\}"));
+        } else {
+            try!(write!(self.wr, "\\{"));
+            self.indent += 2;
+            f(self);
+            self.indent -= 2;
+            try!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
+        }
+    }
+
+    fn emit_struct_field(&mut self,
+                         name: &str,
+                         idx: uint,
+                         f: |&mut PrettyEncoder<'a>|) {
+        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);
+    }
+
+    fn emit_tuple(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
+        self.emit_seq(len, f)
+    }
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
+        self.emit_seq_elt(idx, f)
+    }
+
+    fn emit_tuple_struct(&mut self,
+                         _: &str,
+                         len: uint,
+                         f: |&mut PrettyEncoder<'a>|) {
+        self.emit_seq(len, f)
+    }
+    fn emit_tuple_struct_arg(&mut self,
+                             idx: uint,
+                             f: |&mut PrettyEncoder<'a>|) {
+        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_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
+        if len == 0 {
+            try!(write!(self.wr, "[]"));
+        } else {
+            try!(write!(self.wr, "["));
+            self.indent += 2;
+            f(self);
+            self.indent -= 2;
+            try!(write!(self.wr, "\n{}]", spaces(self.indent)));
+        }
+    }
+
+    fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
+        if idx == 0 {
+            try!(write!(self.wr, "\n"));
+        } else {
+            try!(write!(self.wr, ",\n"));
+        }
+        try!(write!(self.wr, "{}", spaces(self.indent)));
+        f(self)
+    }
+
+    fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
+        if len == 0 {
+            try!(write!(self.wr, "\\{\\}"));
+        } else {
+            try!(write!(self.wr, "\\{"));
+            self.indent += 2;
+            f(self);
+            self.indent -= 2;
+            try!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
+        }
+    }
+
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
+        use std::str::from_utf8;
+        if idx == 0 {
+            try!(write!(self.wr, "\n"));
+        } else {
+            try!(write!(self.wr, ",\n"));
+        }
+        try!(write!(self.wr, "{}", spaces(self.indent)));
+        // 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 = PrettyEncoder::new(&mut buf);
+        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);
+        if needs_wrapping { try!(write!(self.wr, "\"")); }
+    }
+
+    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) {
+        try!(write!(self.wr, ": "));
+        f(self);
+    }
+}
+
+impl<E: ::Encoder> Encodable<E> for Json {
+    fn encode(&self, e: &mut E) {
+        match *self {
+            Number(v) => v.encode(e),
+            String(ref v) => v.encode(e),
+            Boolean(v) => v.encode(e),
+            List(ref v) => v.encode(e),
+            Object(ref v) => v.encode(e),
+            Null => e.emit_nil(),
+        }
+    }
+}
+
+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<()> {
+        let mut encoder = Encoder::new(wr);
+        self.encode(&mut encoder);
+        encoder.error
+    }
+
+    /// 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<()> {
+        let mut encoder = PrettyEncoder::new(wr);
+        self.encode(&mut encoder);
+        encoder.error
+    }
+
+    /// Encodes a json value into a string
+    pub fn to_pretty_str(&self) -> ~str {
+        let mut s = MemWriter::new();
+        self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
+        str::from_utf8_owned(s.unwrap()).unwrap()
+    }
+
+     /// If the Json value is an Object, returns the value associated with the provided key.
+    /// Otherwise, returns None.
+    pub fn find<'a>(&'a self, key: &~str) -> Option<&'a Json>{
+        match self {
+            &Object(ref map) => map.find(key),
+            _ => None
+        }
+    }
+
+    /// Attempts to get a nested Json Object for each key in `keys`.
+    /// If any key is found not to exist, find_path will return None.
+    /// Otherwise, it will return the Json value associated with the final key.
+    pub fn find_path<'a>(&'a self, keys: &[&~str]) -> Option<&'a Json>{
+        let mut target = self;
+        for key in keys.iter() {
+            match target.find(*key) {
+                Some(t) => { target = t; },
+                None => return None
+            }
+        }
+        Some(target)
+    }
+
+    /// If the Json value is an Object, performs a depth-first search until
+    /// a value associated with the provided key is found. If no value is found
+    /// or the Json value is not an Object, returns None.
+    pub fn search<'a>(&'a self, key: &~str) -> Option<&'a Json> {
+        match self {
+            &Object(ref map) => {
+                match map.find(key) {
+                    Some(json_value) => Some(json_value),
+                    None => {
+                        let mut value : Option<&'a Json> = None;
+                        for (_, v) in map.iter() {
+                            value = v.search(key);
+                            if value.is_some() {
+                                break;
+                            }
+                        }
+                        value
+                    }
+                }
+            },
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is an Object. Returns false otherwise.
+    pub fn is_object<'a>(&'a self) -> bool {
+        self.as_object().is_some()
+    }
+
+    /// If the Json value is an Object, returns the associated TreeMap.
+    /// Returns None otherwise.
+    pub fn as_object<'a>(&'a self) -> Option<&'a Object> {
+        match self {
+            &Object(ref map) => Some(&**map),
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is a List. Returns false otherwise.
+    pub fn is_list<'a>(&'a self) -> bool {
+        self.as_list().is_some()
+    }
+
+    /// If the Json value is a List, returns the associated vector.
+    /// Returns None otherwise.
+    pub fn as_list<'a>(&'a self) -> Option<&'a List> {
+        match self {
+            &List(ref list) => Some(&*list),
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is a String. Returns false otherwise.
+    pub fn is_string<'a>(&'a self) -> bool {
+        self.as_string().is_some()
+    }
+
+    /// If the Json value is a String, returns the associated str.
+    /// Returns None otherwise.
+    pub fn as_string<'a>(&'a self) -> Option<&'a str> {
+        match *self {
+            String(ref s) => Some(s.as_slice()),
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is a Number. Returns false otherwise.
+    pub fn is_number(&self) -> bool {
+        self.as_number().is_some()
+    }
+
+    /// If the Json value is a Number, returns the associated f64.
+    /// Returns None otherwise.
+    pub fn as_number(&self) -> Option<f64> {
+        match self {
+            &Number(n) => Some(n),
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is a Boolean. Returns false otherwise.
+    pub fn is_boolean(&self) -> bool {
+        self.as_boolean().is_some()
+    }
+
+    /// If the Json value is a Boolean, returns the associated bool.
+    /// Returns None otherwise.
+    pub fn as_boolean(&self) -> Option<bool> {
+        match self {
+            &Boolean(b) => Some(b),
+            _ => None
+        }
+    }
+
+    /// Returns true if the Json value is a Null. Returns false otherwise.
+    pub fn is_null(&self) -> bool {
+        self.as_null().is_some()
+    }
+
+    /// If the Json value is a Null, returns ().
+    /// Returns None otherwise.
+    pub fn as_null(&self) -> Option<()> {
+        match self {
+            &Null => Some(()),
+            _ => None
+        }
+    }
+}
+
+pub struct Parser<T> {
+    priv rdr: T,
+    priv ch: Option<char>,
+    priv line: uint,
+    priv col: uint,
+}
+
+impl<T: Iterator<char>> Parser<T> {
+    /// Decode a json value from an Iterator<char>
+    pub fn new(rdr: T) -> Parser<T> {
+        let mut p = Parser {
+            rdr: rdr,
+            ch: Some('\x00'),
+            line: 1,
+            col: 0,
+        };
+        p.bump();
+        p
+    }
+}
+
+impl<T: Iterator<char>> Parser<T> {
+    pub fn parse(&mut self) -> Result<Json, Error> {
+        match self.parse_value() {
+          Ok(value) => {
+            // Skip trailing whitespaces.
+            self.parse_whitespace();
+            // Make sure there is no trailing characters.
+            if self.eof() {
+                Ok(value)
+            } else {
+                self.error(~"trailing characters")
+            }
+          }
+          Err(e) => Err(e)
+        }
+    }
+}
+
+impl<T : Iterator<char>> Parser<T> {
+    fn eof(&self) -> bool { self.ch.is_none() }
+    fn ch_or_null(&self) -> char { self.ch.unwrap_or('\x00') }
+    fn bump(&mut self) {
+        self.ch = self.rdr.next();
+
+        if self.ch_is('\n') {
+            self.line += 1u;
+            self.col = 1u;
+        } else {
+            self.col += 1u;
+        }
+    }
+
+    fn next_char(&mut self) -> Option<char> {
+        self.bump();
+        self.ch
+    }
+    fn ch_is(&self, c: char) -> bool {
+        self.ch == Some(c)
+    }
+
+    fn error<T>(&self, msg: ~str) -> Result<T, Error> {
+        Err(Error { line: self.line, col: self.col, msg: msg })
+    }
+
+    fn parse_value(&mut self) -> Result<Json, Error> {
+        self.parse_whitespace();
+
+        if self.eof() { return self.error(~"EOF while parsing value"); }
+
+        match self.ch_or_null() {
+            'n' => self.parse_ident("ull", Null),
+            't' => self.parse_ident("rue", Boolean(true)),
+            'f' => self.parse_ident("alse", Boolean(false)),
+            '0' .. '9' | '-' => self.parse_number(),
+            '"' => {
+                match self.parse_str() {
+                    Ok(s) => Ok(String(s)),
+                    Err(e) => Err(e),
+                }
+            },
+            '[' => self.parse_list(),
+            '{' => self.parse_object(),
+            _ => self.error(~"invalid syntax"),
+        }
+    }
+
+    fn parse_whitespace(&mut self) {
+        while self.ch_is(' ') ||
+              self.ch_is('\n') ||
+              self.ch_is('\t') ||
+              self.ch_is('\r') { self.bump(); }
+    }
+
+    fn parse_ident(&mut self, ident: &str, value: Json) -> Result<Json, Error> {
+        if ident.chars().all(|c| Some(c) == self.next_char()) {
+            self.bump();
+            Ok(value)
+        } else {
+            self.error(~"invalid syntax")
+        }
+    }
+
+    fn parse_number(&mut self) -> Result<Json, Error> {
+        let mut neg = 1.0;
+
+        if self.ch_is('-') {
+            self.bump();
+            neg = -1.0;
+        }
+
+        let mut res = match self.parse_integer() {
+          Ok(res) => res,
+          Err(e) => return Err(e)
+        };
+
+        if self.ch_is('.') {
+            match self.parse_decimal(res) {
+              Ok(r) => res = r,
+              Err(e) => return Err(e)
+            }
+        }
+
+        if self.ch_is('e') || self.ch_is('E') {
+            match self.parse_exponent(res) {
+              Ok(r) => res = r,
+              Err(e) => return Err(e)
+            }
+        }
+
+        Ok(Number(neg * res))
+    }
+
+    fn parse_integer(&mut self) -> Result<f64, Error> {
+        let mut res = 0.0;
+
+        match self.ch_or_null() {
+            '0' => {
+                self.bump();
+
+                // There can be only one leading '0'.
+                match self.ch_or_null() {
+                    '0' .. '9' => return self.error(~"invalid number"),
+                    _ => ()
+                }
+            },
+            '1' .. '9' => {
+                while !self.eof() {
+                    match self.ch_or_null() {
+                        c @ '0' .. '9' => {
+                            res *= 10.0;
+                            res += ((c as int) - ('0' as int)) as f64;
+
+                            self.bump();
+                        }
+                        _ => break,
+                    }
+                }
+            }
+            _ => return self.error(~"invalid number"),
+        }
+        Ok(res)
+    }
+
+    fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
+        self.bump();
+
+        // Make sure a digit follows the decimal place.
+        match self.ch_or_null() {
+            '0' .. '9' => (),
+             _ => return self.error(~"invalid number")
+        }
+
+        let mut res = res;
+        let mut dec = 1.0;
+        while !self.eof() {
+            match self.ch_or_null() {
+                c @ '0' .. '9' => {
+                    dec /= 10.0;
+                    res += (((c as int) - ('0' as int)) as f64) * dec;
+
+                    self.bump();
+                }
+                _ => break,
+            }
+        }
+
+        Ok(res)
+    }
+
+    fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
+        self.bump();
+
+        let mut exp = 0u;
+        let mut neg_exp = false;
+
+        if self.ch_is('+') {
+            self.bump();
+        } else if self.ch_is('-') {
+            self.bump();
+            neg_exp = true;
+        }
+
+        // Make sure a digit follows the exponent place.
+        match self.ch_or_null() {
+            '0' .. '9' => (),
+            _ => return self.error(~"invalid number")
+        }
+        while !self.eof() {
+            match self.ch_or_null() {
+                c @ '0' .. '9' => {
+                    exp *= 10;
+                    exp += (c as uint) - ('0' as uint);
+
+                    self.bump();
+                }
+                _ => break
+            }
+        }
+
+        let exp: f64 = num::pow(10u as f64, exp);
+        if neg_exp {
+            res /= exp;
+        } else {
+            res *= exp;
+        }
+
+        Ok(res)
+    }
+
+    fn parse_str(&mut self) -> Result<~str, Error> {
+        let mut escape = false;
+        let mut res = ~"";
+
+        loop {
+            self.bump();
+            if self.eof() {
+                return self.error(~"EOF while parsing string");
+            }
+
+            if escape {
+                match self.ch_or_null() {
+                    '"' => res.push_char('"'),
+                    '\\' => res.push_char('\\'),
+                    '/' => res.push_char('/'),
+                    'b' => res.push_char('\x08'),
+                    'f' => res.push_char('\x0c'),
+                    'n' => res.push_char('\n'),
+                    'r' => res.push_char('\r'),
+                    't' => res.push_char('\t'),
+                    'u' => {
+                        // Parse \u1234.
+                        let mut i = 0u;
+                        let mut n = 0u;
+                        while i < 4u && !self.eof() {
+                            self.bump();
+                            n = match self.ch_or_null() {
+                                c @ '0' .. '9' => n * 16u + (c as uint) - ('0' as uint),
+                                'a' | 'A' => n * 16u + 10u,
+                                'b' | 'B' => n * 16u + 11u,
+                                'c' | 'C' => n * 16u + 12u,
+                                'd' | 'D' => n * 16u + 13u,
+                                'e' | 'E' => n * 16u + 14u,
+                                'f' | 'F' => n * 16u + 15u,
+                                _ => return self.error(
+                                    ~"invalid \\u escape (unrecognized hex)")
+                            };
+
+                            i += 1u;
+                        }
+
+                        // Error out if we didn't parse 4 digits.
+                        if i != 4u {
+                            return self.error(
+                                ~"invalid \\u escape (not four digits)");
+                        }
+
+                        res.push_char(char::from_u32(n as u32).unwrap());
+                    }
+                    _ => return self.error(~"invalid escape"),
+                }
+                escape = false;
+            } else if self.ch_is('\\') {
+                escape = true;
+            } else {
+                match self.ch {
+                    Some('"') => { self.bump(); return Ok(res); },
+                    Some(c) => res.push_char(c),
+                    None => unreachable!()
+                }
+            }
+        }
+    }
+
+    fn parse_list(&mut self) -> Result<Json, Error> {
+        self.bump();
+        self.parse_whitespace();
+
+        let mut values = ~[];
+
+        if self.ch_is(']') {
+            self.bump();
+            return Ok(List(values));
+        }
+
+        loop {
+            match self.parse_value() {
+              Ok(v) => values.push(v),
+              Err(e) => return Err(e)
+            }
+
+            self.parse_whitespace();
+            if self.eof() {
+                return self.error(~"EOF while parsing list");
+            }
+
+            if self.ch_is(',') {
+                self.bump();
+            } else if self.ch_is(']') {
+                self.bump();
+                return Ok(List(values));
+            } else {
+                return self.error(~"expected `,` or `]`")
+            }
+        };
+    }
+
+    fn parse_object(&mut self) -> Result<Json, Error> {
+        self.bump();
+        self.parse_whitespace();
+
+        let mut values = ~TreeMap::new();
+
+        if self.ch_is('}') {
+          self.bump();
+          return Ok(Object(values));
+        }
+
+        while !self.eof() {
+            self.parse_whitespace();
+
+            if !self.ch_is('"') {
+                return self.error(~"key must be a string");
+            }
+
+            let key = match self.parse_str() {
+              Ok(key) => key,
+              Err(e) => return Err(e)
+            };
+
+            self.parse_whitespace();
+
+            if !self.ch_is(':') {
+                if self.eof() { break; }
+                return self.error(~"expected `:`");
+            }
+            self.bump();
+
+            match self.parse_value() {
+              Ok(value) => { values.insert(key, value); }
+              Err(e) => return Err(e)
+            }
+            self.parse_whitespace();
+
+            match self.ch_or_null() {
+                ',' => self.bump(),
+                '}' => { self.bump(); return Ok(Object(values)); },
+                _ => {
+                    if self.eof() { break; }
+                    return self.error(~"expected `,` or `}`");
+                }
+            }
+        }
+
+        return self.error(~"EOF while parsing object");
+    }
+}
+
+/// Decodes a json value from an `&mut io::Reader`
+pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> {
+    let contents = match rdr.read_to_end() {
+        Ok(c) => c,
+        Err(e) => return Err(io_error_to_error(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" })
+    };
+    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> {
+    let mut parser = Parser::new(s.chars());
+    parser.parse()
+}
+
+/// A structure to decode JSON to values in rust.
+pub struct Decoder {
+    priv stack: ~[Json],
+}
+
+impl Decoder {
+    /// Creates a new decoder instance for decoding the specified JSON value.
+    pub fn new(json: Json) -> Decoder {
+        Decoder {
+            stack: ~[json]
+        }
+    }
+}
+
+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()))
+    }
+}
+
+impl ::Decoder for Decoder {
+    fn read_nil(&mut self) -> () {
+        debug!("read_nil");
+        match self.stack.pop().unwrap() {
+            Null => (),
+            value => self.expected("null", &value)
+        }
+    }
+
+    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_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_bool(&mut self) -> bool {
+        debug!("read_bool");
+        match self.stack.pop().unwrap() {
+            Boolean(b) => b,
+            value => self.expected("boolean", &value)
+        }
+    }
+
+    fn read_f64(&mut self) -> f64 {
+        use std::from_str::FromStr;
+        debug!("read_f64");
+        match self.stack.pop().unwrap() {
+            Number(f) => 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()
+            },
+            value => self.expected("number", &value)
+        }
+    }
+
+    fn read_f32(&mut self) -> f32 { self.read_f64() as f32 }
+
+    fn read_char(&mut self) -> char {
+        let s = self.read_str();
+        {
+            let mut it = s.chars();
+            match (it.next(), it.next()) {
+                // exactly one character
+                (Some(c), None) => return c,
+                _ => ()
+            }
+        }
+        self.expected("single character string", &String(s))
+    }
+
+    fn read_str(&mut self) -> ~str {
+        debug!("read_str");
+        match self.stack.pop().unwrap() {
+            String(s) => s,
+            value => self.expected("string", &value)
+        }
+    }
+
+    fn read_enum<T>(&mut self, name: &str, f: |&mut Decoder| -> T) -> T {
+        debug!("read_enum({})", name);
+        f(self)
+    }
+
+    fn read_enum_variant<T>(&mut self,
+                            names: &[&str],
+                            f: |&mut Decoder, uint| -> T)
+                            -> T {
+        debug!("read_enum_variant(names={:?})", names);
+        let name = match self.stack.pop().unwrap() {
+            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)
+                };
+                match o.pop(&~"fields") {
+                    Some(List(l)) => {
+                        for field in l.move_rev_iter() {
+                            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);
+                    }
+                }
+                n
+            }
+            json => self.expected("string or object", &json)
+        };
+        let idx = match names.iter().position(|n| str::eq_slice(*n, name)) {
+            Some(idx) => idx,
+            None => self.err(format!("unknown variant name: {}", name))
+        };
+        f(self, idx)
+    }
+
+    fn read_enum_variant_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> T)
+                                -> 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 {
+        debug!("read_enum_struct_variant(names={:?})", names);
+        self.read_enum_variant(names, f)
+    }
+
+
+    fn read_enum_struct_variant_field<T>(&mut self,
+                                         name: &str,
+                                         idx: uint,
+                                         f: |&mut Decoder| -> T)
+                                         -> T {
+        debug!("read_enum_struct_variant_field(name={}, idx={})", name, idx);
+        self.read_enum_variant_arg(idx, f)
+    }
+
+    fn read_struct<T>(&mut self,
+                      name: &str,
+                      len: uint,
+                      f: |&mut Decoder| -> T)
+                      -> T {
+        debug!("read_struct(name={}, len={})", name, len);
+        let value = f(self);
+        self.stack.pop().unwrap();
+        value
+    }
+
+    fn read_struct_field<T>(&mut self,
+                            name: &str,
+                            idx: uint,
+                            f: |&mut Decoder| -> T)
+                            -> 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
+            }
+            value => self.expected("object", &value)
+        }
+    }
+
+    fn read_tuple<T>(&mut self, f: |&mut Decoder, uint| -> T) -> T {
+        debug!("read_tuple()");
+        self.read_seq(f)
+    }
+
+    fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> 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 {
+        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 {
+        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() {
+            Null => f(self, false),
+            value => { self.stack.push(value); f(self, true) }
+        }
+    }
+
+    fn read_seq<T>(&mut self, f: |&mut Decoder, uint| -> T) -> 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)
+        };
+        f(self, len)
+    }
+
+    fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder| -> T) -> T {
+        debug!("read_seq_elt(idx={})", idx);
+        f(self)
+    }
+
+    fn read_map<T>(&mut self, f: |&mut Decoder, uint| -> T) -> 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)
+        };
+        f(self, len)
+    }
+
+    fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder| -> T)
+                           -> 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 {
+        debug!("read_map_elt_val(idx={})", idx);
+        f(self)
+    }
+}
+
+/// Test if two json values are less than one another
+impl Ord for Json {
+    fn lt(&self, other: &Json) -> bool {
+        match *self {
+            Number(f0) => {
+                match *other {
+                    Number(f1) => f0 < f1,
+                    String(_) | Boolean(_) | List(_) | Object(_) |
+                    Null => true
+                }
+            }
+
+            String(ref s0) => {
+                match *other {
+                    Number(_) => false,
+                    String(ref s1) => s0 < s1,
+                    Boolean(_) | List(_) | Object(_) | Null => true
+                }
+            }
+
+            Boolean(b0) => {
+                match *other {
+                    Number(_) | String(_) => false,
+                    Boolean(b1) => b0 < b1,
+                    List(_) | Object(_) | Null => true
+                }
+            }
+
+            List(ref l0) => {
+                match *other {
+                    Number(_) | String(_) | Boolean(_) => false,
+                    List(ref l1) => (*l0) < (*l1),
+                    Object(_) | Null => true
+                }
+            }
+
+            Object(ref d0) => {
+                match *other {
+                    Number(_) | String(_) | Boolean(_) | List(_) => false,
+                    Object(ref d1) => d0 < d1,
+                    Null => true
+                }
+            }
+
+            Null => {
+                match *other {
+                    Number(_) | String(_) | Boolean(_) | List(_) |
+                    Object(_) =>
+                        false,
+                    Null => true
+                }
+            }
+        }
+    }
+}
+
+/// A trait for converting values to JSON
+pub trait ToJson {
+    /// Converts the value of `self` to an instance of JSON
+    fn to_json(&self) -> Json;
+}
+
+impl ToJson for Json {
+    fn to_json(&self) -> Json { (*self).clone() }
+}
+
+impl ToJson for int {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for i8 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for i16 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for i32 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for i64 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for uint {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for u8 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for u16 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for u32 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for u64 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for f32 {
+    fn to_json(&self) -> Json { Number(*self as f64) }
+}
+
+impl ToJson for f64 {
+    fn to_json(&self) -> Json { Number(*self) }
+}
+
+impl ToJson for () {
+    fn to_json(&self) -> Json { Null }
+}
+
+impl ToJson for bool {
+    fn to_json(&self) -> Json { Boolean(*self) }
+}
+
+impl ToJson for ~str {
+    fn to_json(&self) -> Json { String((*self).clone()) }
+}
+
+impl<A:ToJson,B:ToJson> ToJson for (A, B) {
+    fn to_json(&self) -> Json {
+        match *self {
+          (ref a, ref b) => {
+            List(~[a.to_json(), b.to_json()])
+          }
+        }
+    }
+}
+
+impl<A:ToJson,B:ToJson,C:ToJson> ToJson for (A, B, C) {
+    fn to_json(&self) -> Json {
+        match *self {
+          (ref a, ref b, ref c) => {
+            List(~[a.to_json(), b.to_json(), c.to_json()])
+          }
+        }
+    }
+}
+
+impl<A:ToJson> ToJson for ~[A] {
+    fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
+}
+
+impl<A:ToJson> ToJson for TreeMap<~str, A> {
+    fn to_json(&self) -> Json {
+        let mut d = TreeMap::new();
+        for (key, value) in self.iter() {
+            d.insert((*key).clone(), value.to_json());
+        }
+        Object(~d)
+    }
+}
+
+impl<A:ToJson> ToJson for HashMap<~str, A> {
+    fn to_json(&self) -> Json {
+        let mut d = TreeMap::new();
+        for (key, value) in self.iter() {
+            d.insert((*key).clone(), value.to_json());
+        }
+        Object(~d)
+    }
+}
+
+impl<A:ToJson> ToJson for Option<A> {
+    fn to_json(&self) -> Json {
+        match *self {
+          None => Null,
+          Some(ref value) => value.to_json()
+        }
+    }
+}
+
+impl fmt::Show for Json {
+    /// Encodes a json value into a string
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.to_writer(f.buf)
+    }
+}
+
+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};
+    use std::io;
+    use collections::TreeMap;
+
+    #[deriving(Eq, Encodable, Decodable, Show)]
+    enum Animal {
+        Dog,
+        Frog(~str, int)
+    }
+
+    #[deriving(Eq, Encodable, Decodable, Show)]
+    struct Inner {
+        a: (),
+        b: uint,
+        c: ~[~str],
+    }
+
+    #[deriving(Eq, Encodable, Decodable, Show)]
+    struct Outer {
+        inner: ~[Inner],
+    }
+
+    fn mk_object(items: &[(~str, Json)]) -> Json {
+        let mut d = ~TreeMap::new();
+
+        for item in items.iter() {
+            match *item {
+                (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); },
+            }
+        };
+
+        Object(d)
+    }
+
+    #[test]
+    fn test_write_null() {
+        assert_eq!(Null.to_str(), ~"null");
+        assert_eq!(Null.to_pretty_str(), ~"null");
+    }
+
+
+    #[test]
+    fn test_write_number() {
+        assert_eq!(Number(3.0).to_str(), ~"3");
+        assert_eq!(Number(3.0).to_pretty_str(), ~"3");
+
+        assert_eq!(Number(3.1).to_str(), ~"3.1");
+        assert_eq!(Number(3.1).to_pretty_str(), ~"3.1");
+
+        assert_eq!(Number(-1.5).to_str(), ~"-1.5");
+        assert_eq!(Number(-1.5).to_pretty_str(), ~"-1.5");
+
+        assert_eq!(Number(0.5).to_str(), ~"0.5");
+        assert_eq!(Number(0.5).to_pretty_str(), ~"0.5");
+    }
+
+    #[test]
+    fn test_write_str() {
+        assert_eq!(String(~"").to_str(), ~"\"\"");
+        assert_eq!(String(~"").to_pretty_str(), ~"\"\"");
+
+        assert_eq!(String(~"foo").to_str(), ~"\"foo\"");
+        assert_eq!(String(~"foo").to_pretty_str(), ~"\"foo\"");
+    }
+
+    #[test]
+    fn test_write_bool() {
+        assert_eq!(Boolean(true).to_str(), ~"true");
+        assert_eq!(Boolean(true).to_pretty_str(), ~"true");
+
+        assert_eq!(Boolean(false).to_str(), ~"false");
+        assert_eq!(Boolean(false).to_pretty_str(), ~"false");
+    }
+
+    #[test]
+    fn test_write_list() {
+        assert_eq!(List(~[]).to_str(), ~"[]");
+        assert_eq!(List(~[]).to_pretty_str(), ~"[]");
+
+        assert_eq!(List(~[Boolean(true)]).to_str(), ~"[true]");
+        assert_eq!(
+            List(~[Boolean(true)]).to_pretty_str(),
+            ~"\
+            [\n  \
+                true\n\
+            ]"
+        );
+
+        let long_test_list = List(~[
+            Boolean(false),
+            Null,
+            List(~[String(~"foo\nbar"), Number(3.5)])]);
+
+        assert_eq!(long_test_list.to_str(),
+            ~"[false,null,[\"foo\\nbar\",3.5]]");
+        assert_eq!(
+            long_test_list.to_pretty_str(),
+            ~"\
+            [\n  \
+                false,\n  \
+                null,\n  \
+                [\n    \
+                    \"foo\\nbar\",\n    \
+                    3.5\n  \
+                ]\n\
+            ]"
+        );
+    }
+
+    #[test]
+    fn test_write_object() {
+        assert_eq!(mk_object([]).to_str(), ~"{}");
+        assert_eq!(mk_object([]).to_pretty_str(), ~"{}");
+
+        assert_eq!(
+            mk_object([(~"a", Boolean(true))]).to_str(),
+            ~"{\"a\":true}"
+        );
+        assert_eq!(
+            mk_object([(~"a", Boolean(true))]).to_pretty_str(),
+            ~"\
+            {\n  \
+                \"a\": true\n\
+            }"
+        );
+
+        let complex_obj = mk_object([
+                (~"b", List(~[
+                    mk_object([(~"c", String(~"\x0c\r"))]),
+                    mk_object([(~"d", String(~""))])
+                ]))
+            ]);
+
+        assert_eq!(
+            complex_obj.to_str(),
+            ~"{\
+                \"b\":[\
+                    {\"c\":\"\\f\\r\"},\
+                    {\"d\":\"\"}\
+                ]\
+            }"
+        );
+        assert_eq!(
+            complex_obj.to_pretty_str(),
+            ~"\
+            {\n  \
+                \"b\": [\n    \
+                    {\n      \
+                        \"c\": \"\\f\\r\"\n    \
+                    },\n    \
+                    {\n      \
+                        \"d\": \"\"\n    \
+                    }\n  \
+                ]\n\
+            }"
+        );
+
+        let a = mk_object([
+            (~"a", Boolean(true)),
+            (~"b", List(~[
+                mk_object([(~"c", String(~"\x0c\r"))]),
+                mk_object([(~"d", String(~""))])
+            ]))
+        ]);
+
+        // We can't compare the strings directly because the object fields be
+        // printed in a different order.
+        assert_eq!(a.clone(), from_str(a.to_str()).unwrap());
+        assert_eq!(a.clone(), from_str(a.to_pretty_str()).unwrap());
+    }
+
+    fn with_str_writer(f: |&mut io::Writer|) -> ~str {
+        use std::io::MemWriter;
+        use std::str;
+
+        let mut m = MemWriter::new();
+        f(&mut m as &mut io::Writer);
+        str::from_utf8_owned(m.unwrap()).unwrap()
+    }
+
+    #[test]
+    fn test_write_enum() {
+        let animal = Dog;
+        assert_eq!(
+            with_str_writer(|wr| {
+                let mut encoder = Encoder::new(wr);
+                animal.encode(&mut encoder);
+            }),
+            ~"\"Dog\""
+        );
+        assert_eq!(
+            with_str_writer(|wr| {
+                let mut encoder = PrettyEncoder::new(wr);
+                animal.encode(&mut encoder);
+            }),
+            ~"\"Dog\""
+        );
+
+        let animal = Frog(~"Henry", 349);
+        assert_eq!(
+            with_str_writer(|wr| {
+                let mut encoder = Encoder::new(wr);
+                animal.encode(&mut encoder);
+            }),
+            ~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
+        );
+        assert_eq!(
+            with_str_writer(|wr| {
+                let mut encoder = PrettyEncoder::new(wr);
+                animal.encode(&mut encoder);
+            }),
+            ~"\
+            [\n  \
+                \"Frog\",\n  \
+                \"Henry\",\n  \
+                349\n\
+            ]"
+        );
+    }
+
+    #[test]
+    fn test_write_some() {
+        let value = Some(~"jodhpurs");
+        let s = with_str_writer(|wr| {
+            let mut encoder = Encoder::new(wr);
+            value.encode(&mut encoder);
+        });
+        assert_eq!(s, ~"\"jodhpurs\"");
+
+        let value = Some(~"jodhpurs");
+        let s = with_str_writer(|wr| {
+            let mut encoder = PrettyEncoder::new(wr);
+            value.encode(&mut encoder);
+        });
+        assert_eq!(s, ~"\"jodhpurs\"");
+    }
+
+    #[test]
+    fn test_write_none() {
+        let value: Option<~str> = None;
+        let s = with_str_writer(|wr| {
+            let mut encoder = Encoder::new(wr);
+            value.encode(&mut encoder);
+        });
+        assert_eq!(s, ~"null");
+
+        let s = with_str_writer(|wr| {
+            let mut encoder = Encoder::new(wr);
+            value.encode(&mut encoder);
+        });
+        assert_eq!(s, ~"null");
+    }
+
+    #[test]
+    fn test_trailing_characters() {
+        assert_eq!(from_str("nulla"),
+            Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"}));
+        assert_eq!(from_str("truea"),
+            Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"}));
+        assert_eq!(from_str("falsea"),
+            Err(Error {line: 1u, col: 6u, msg: ~"trailing characters"}));
+        assert_eq!(from_str("1a"),
+            Err(Error {line: 1u, col: 2u, msg: ~"trailing characters"}));
+        assert_eq!(from_str("[]a"),
+            Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"}));
+        assert_eq!(from_str("{}a"),
+            Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"}));
+    }
+
+    #[test]
+    fn test_read_identifiers() {
+        assert_eq!(from_str("n"),
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
+        assert_eq!(from_str("nul"),
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
+
+        assert_eq!(from_str("t"),
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
+        assert_eq!(from_str("truz"),
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
+
+        assert_eq!(from_str("f"),
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
+        assert_eq!(from_str("faz"),
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid syntax"}));
+
+        assert_eq!(from_str("null"), Ok(Null));
+        assert_eq!(from_str("true"), Ok(Boolean(true)));
+        assert_eq!(from_str("false"), Ok(Boolean(false)));
+        assert_eq!(from_str(" null "), Ok(Null));
+        assert_eq!(from_str(" true "), Ok(Boolean(true)));
+        assert_eq!(from_str(" false "), Ok(Boolean(false)));
+    }
+
+    #[test]
+    fn test_decode_identifiers() {
+        let mut decoder = Decoder::new(from_str("null").unwrap());
+        let v: () = Decodable::decode(&mut decoder);
+        assert_eq!(v, ());
+
+        let mut decoder = Decoder::new(from_str("true").unwrap());
+        let v: bool = Decodable::decode(&mut decoder);
+        assert_eq!(v, true);
+
+        let mut decoder = Decoder::new(from_str("false").unwrap());
+        let v: bool = Decodable::decode(&mut decoder);
+        assert_eq!(v, false);
+    }
+
+    #[test]
+    fn test_read_number() {
+        assert_eq!(from_str("+"),
+            Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"}));
+        assert_eq!(from_str("."),
+            Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"}));
+
+        assert_eq!(from_str("-"),
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid number"}));
+        assert_eq!(from_str("00"),
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid number"}));
+        assert_eq!(from_str("1."),
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid number"}));
+        assert_eq!(from_str("1e"),
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid number"}));
+        assert_eq!(from_str("1e+"),
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid number"}));
+
+        assert_eq!(from_str("3"), Ok(Number(3.0)));
+        assert_eq!(from_str("3.1"), Ok(Number(3.1)));
+        assert_eq!(from_str("-1.2"), Ok(Number(-1.2)));
+        assert_eq!(from_str("0.4"), Ok(Number(0.4)));
+        assert_eq!(from_str("0.4e5"), Ok(Number(0.4e5)));
+        assert_eq!(from_str("0.4e+15"), Ok(Number(0.4e15)));
+        assert_eq!(from_str("0.4e-01"), Ok(Number(0.4e-01)));
+        assert_eq!(from_str(" 3 "), Ok(Number(3.0)));
+    }
+
+    #[test]
+    fn test_decode_numbers() {
+        let mut decoder = Decoder::new(from_str("3").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, 3.0);
+
+        let mut decoder = Decoder::new(from_str("3.1").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, 3.1);
+
+        let mut decoder = Decoder::new(from_str("-1.2").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, -1.2);
+
+        let mut decoder = Decoder::new(from_str("0.4").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, 0.4);
+
+        let mut decoder = Decoder::new(from_str("0.4e5").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, 0.4e5);
+
+        let mut decoder = Decoder::new(from_str("0.4e15").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        assert_eq!(v, 0.4e15);
+
+        let mut decoder = Decoder::new(from_str("0.4e-01").unwrap());
+        let v: f64 = Decodable::decode(&mut decoder);
+        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"
+        }));
+        assert_eq!(from_str("\"lol"),
+            Err(Error {line: 1u, col: 5u, msg: ~"EOF while parsing string"
+        }));
+
+        assert_eq!(from_str("\"\""), Ok(String(~"")));
+        assert_eq!(from_str("\"foo\""), Ok(String(~"foo")));
+        assert_eq!(from_str("\"\\\"\""), Ok(String(~"\"")));
+        assert_eq!(from_str("\"\\b\""), Ok(String(~"\x08")));
+        assert_eq!(from_str("\"\\n\""), Ok(String(~"\n")));
+        assert_eq!(from_str("\"\\r\""), Ok(String(~"\r")));
+        assert_eq!(from_str("\"\\t\""), Ok(String(~"\t")));
+        assert_eq!(from_str(" \"foo\" "), Ok(String(~"foo")));
+        assert_eq!(from_str("\"\\u12ab\""), Ok(String(~"\u12ab")));
+        assert_eq!(from_str("\"\\uAB12\""), Ok(String(~"\uAB12")));
+    }
+
+    #[test]
+    fn test_decode_str() {
+        let mut decoder = Decoder::new(from_str("\"\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"");
+
+        let mut decoder = Decoder::new(from_str("\"foo\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"foo");
+
+        let mut decoder = Decoder::new(from_str("\"\\\"\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\"");
+
+        let mut decoder = Decoder::new(from_str("\"\\b\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\x08");
+
+        let mut decoder = Decoder::new(from_str("\"\\n\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\n");
+
+        let mut decoder = Decoder::new(from_str("\"\\r\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\r");
+
+        let mut decoder = Decoder::new(from_str("\"\\t\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\t");
+
+        let mut decoder = Decoder::new(from_str("\"\\u12ab\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\u12ab");
+
+        let mut decoder = Decoder::new(from_str("\"\\uAB12\"").unwrap());
+        let v: ~str = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~"\uAB12");
+    }
+
+    #[test]
+    fn test_read_list() {
+        assert_eq!(from_str("["),
+            Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing value"}));
+        assert_eq!(from_str("[1"),
+            Err(Error {line: 1u, col: 3u, msg: ~"EOF while parsing list"}));
+        assert_eq!(from_str("[1,"),
+            Err(Error {line: 1u, col: 4u, msg: ~"EOF while parsing value"}));
+        assert_eq!(from_str("[1,]"),
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
+        assert_eq!(from_str("[6 7]"),
+            Err(Error {line: 1u, col: 4u, msg: ~"expected `,` or `]`"}));
+
+        assert_eq!(from_str("[]"), Ok(List(~[])));
+        assert_eq!(from_str("[ ]"), Ok(List(~[])));
+        assert_eq!(from_str("[true]"), Ok(List(~[Boolean(true)])));
+        assert_eq!(from_str("[ false ]"), Ok(List(~[Boolean(false)])));
+        assert_eq!(from_str("[null]"), Ok(List(~[Null])));
+        assert_eq!(from_str("[3, 1]"),
+                     Ok(List(~[Number(3.0), Number(1.0)])));
+        assert_eq!(from_str("\n[3, 2]\n"),
+                     Ok(List(~[Number(3.0), Number(2.0)])));
+        assert_eq!(from_str("[2, [4, 1]]"),
+               Ok(List(~[Number(2.0), List(~[Number(4.0), Number(1.0)])])));
+    }
+
+    #[test]
+    fn test_decode_list() {
+        let mut decoder = Decoder::new(from_str("[]").unwrap());
+        let v: ~[()] = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~[]);
+
+        let mut decoder = Decoder::new(from_str("[null]").unwrap());
+        let v: ~[()] = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~[()]);
+
+        let mut decoder = Decoder::new(from_str("[true]").unwrap());
+        let v: ~[bool] = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~[true]);
+
+        let mut decoder = Decoder::new(from_str("[true]").unwrap());
+        let v: ~[bool] = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~[true]);
+
+        let mut decoder = Decoder::new(from_str("[3, 1]").unwrap());
+        let v: ~[int] = Decodable::decode(&mut decoder);
+        assert_eq!(v, ~[3, 1]);
+
+        let mut decoder = Decoder::new(from_str("[[3], [1, 2]]").unwrap());
+        let v: ~[~[uint]] = Decodable::decode(&mut decoder);
+        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"}));
+        assert_eq!(from_str("{ "),
+            Err(Error {
+                line: 1u,
+                col: 3u,
+                msg: ~"EOF while parsing object"}));
+        assert_eq!(from_str("{1"),
+            Err(Error {
+                line: 1u,
+                col: 2u,
+                msg: ~"key must be a string"}));
+        assert_eq!(from_str("{ \"a\""),
+            Err(Error {
+                line: 1u,
+                col: 6u,
+                msg: ~"EOF while parsing object"}));
+        assert_eq!(from_str("{\"a\""),
+            Err(Error {
+                line: 1u,
+                col: 5u,
+                msg: ~"EOF while parsing object"}));
+        assert_eq!(from_str("{\"a\" "),
+            Err(Error {
+                line: 1u,
+                col: 6u,
+                msg: ~"EOF while parsing object"}));
+
+        assert_eq!(from_str("{\"a\" 1"),
+            Err(Error {line: 1u, col: 6u, msg: ~"expected `:`"}));
+        assert_eq!(from_str("{\"a\":"),
+            Err(Error {line: 1u, col: 6u, msg: ~"EOF while parsing value"}));
+        assert_eq!(from_str("{\"a\":1"),
+            Err(Error {
+                line: 1u,
+                col: 7u,
+                msg: ~"EOF while parsing object"}));
+        assert_eq!(from_str("{\"a\":1 1"),
+            Err(Error {line: 1u, col: 8u, msg: ~"expected `,` or `}`"}));
+        assert_eq!(from_str("{\"a\":1,"),
+            Err(Error {
+                line: 1u,
+                col: 8u,
+                msg: ~"EOF while parsing object"}));
+
+        assert_eq!(from_str("{}").unwrap(), mk_object([]));
+        assert_eq!(from_str("{\"a\": 3}").unwrap(),
+                  mk_object([(~"a", Number(3.0))]));
+
+        assert_eq!(from_str(
+                      "{ \"a\": null, \"b\" : true }").unwrap(),
+                  mk_object([
+                      (~"a", Null),
+                      (~"b", Boolean(true))]));
+        assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(),
+                  mk_object([
+                      (~"a", Null),
+                      (~"b", Boolean(true))]));
+        assert_eq!(from_str(
+                      "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(),
+                  mk_object([
+                      (~"a", Number(1.0)),
+                      (~"b", List(~[Boolean(true)]))
+                  ]));
+        assert_eq!(from_str(
+                      ~"{" +
+                          "\"a\": 1.0, " +
+                          "\"b\": [" +
+                              "true," +
+                              "\"foo\\nbar\", " +
+                              "{ \"c\": {\"d\": null} } " +
+                          "]" +
+                      "}").unwrap(),
+                  mk_object([
+                      (~"a", Number(1.0)),
+                      (~"b", List(~[
+                          Boolean(true),
+                          String(~"foo\nbar"),
+                          mk_object([
+                              (~"c", mk_object([(~"d", Null)]))
+                          ])
+                      ]))
+                  ]));
+    }
+
+    #[test]
+    fn test_decode_struct() {
+        let s = ~"{
+            \"inner\": [
+                { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
+            ]
+        }";
+        let mut decoder = Decoder::new(from_str(s).unwrap());
+        let v: Outer = Decodable::decode(&mut decoder);
+        assert_eq!(
+            v,
+            Outer {
+                inner: ~[
+                    Inner { a: (), b: 2, c: ~[~"abc", ~"xyz"] }
+                ]
+            }
+        );
+    }
+
+    #[test]
+    fn test_decode_option() {
+        let mut decoder = Decoder::new(from_str("null").unwrap());
+        let value: Option<~str> = Decodable::decode(&mut decoder);
+        assert_eq!(value, None);
+
+        let mut decoder = Decoder::new(from_str("\"jodhpurs\"").unwrap());
+        let value: Option<~str> = Decodable::decode(&mut decoder);
+        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);
+        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);
+        assert_eq!(value, Frog(~"Henry", 349));
+    }
+
+    #[test]
+    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);
+
+        assert_eq!(map.pop(&~"a"), Some(Dog));
+        assert_eq!(map.pop(&~"b"), Some(Frog(~"Henry", 349)));
+    }
+
+    #[test]
+    fn test_multiline_errors() {
+        assert_eq!(from_str("{\n  \"foo\":\n \"bar\""),
+            Err(Error {
+                line: 3u,
+                col: 8u,
+                msg: ~"EOF while parsing object"}));
+    }
+
+    #[deriving(Decodable)]
+    struct DecodeStruct {
+        x: f64,
+        y: bool,
+        z: ~str,
+        w: ~[DecodeStruct]
+    }
+    #[deriving(Decodable)]
+    enum DecodeEnum {
+        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
+                }
+            }
+        });
+        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),
+            Err(e) => {
+                let err = e.as_ref::<~str>().unwrap();
+                assert!(err.contains(expected_error),
+                        "`{}` errored incorrectly, found `{}` expecting `{}`",
+                        to_parse, *err, expected_error);
+            }
+        }
+    }
+    #[test]
+    fn test_decode_errors_struct() {
+        check_err::<DecodeStruct>("[]", "object but found list");
+        check_err::<DecodeStruct>("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
+                                  "number but found boolean");
+        check_err::<DecodeStruct>("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
+                                  "boolean but found list");
+        check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
+                                  "string but found object");
+        check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
+                                  "list but found null");
+        check_err::<DecodeStruct>("{\"x\": 1, \"y\": true, \"z\": \"\"}",
+                                  "'w' field in object");
+    }
+    #[test]
+    fn test_decode_errors_enum() {
+        check_err::<DecodeEnum>("{}",
+                                "'variant' field in object");
+        check_err::<DecodeEnum>("{\"variant\": 1}",
+                                "string but found number");
+        check_err::<DecodeEnum>("{\"variant\": \"A\"}",
+                                "'fields' field in object");
+        check_err::<DecodeEnum>("{\"variant\": \"A\", \"fields\": null}",
+                                "list but found null");
+        check_err::<DecodeEnum>("{\"variant\": \"C\", \"fields\": []}",
+                                "unknown variant name");
+    }
+
+    #[test]
+    fn test_find(){
+        let json_value = from_str("{\"dog\" : \"cat\"}").unwrap();
+        let found_str = json_value.find(&~"dog");
+        assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cat");
+    }
+
+    #[test]
+    fn test_find_path(){
+        let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap();
+        let found_str = json_value.find_path(&[&~"dog", &~"cat", &~"mouse"]);
+        assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == &"cheese");
+    }
+
+    #[test]
+    fn test_search(){
+        let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap();
+        let found_str = json_value.search(&~"mouse").and_then(|j| j.as_string());
+        assert!(found_str.is_some());
+        assert!(found_str.unwrap() == &"cheese");
+    }
+
+    #[test]
+    fn test_is_object(){
+        let json_value = from_str("{}").unwrap();
+        assert!(json_value.is_object());
+    }
+
+    #[test]
+    fn test_as_object(){
+        let json_value = from_str("{}").unwrap();
+        let json_object = json_value.as_object();
+        assert!(json_object.is_some());
+    }
+
+    #[test]
+    fn test_is_list(){
+        let json_value = from_str("[1, 2, 3]").unwrap();
+        assert!(json_value.is_list());
+    }
+
+    #[test]
+    fn test_as_list(){
+        let json_value = from_str("[1, 2, 3]").unwrap();
+        let json_list = json_value.as_list();
+        let expected_length = 3;
+        assert!(json_list.is_some() && json_list.unwrap().len() == expected_length);
+    }
+
+    #[test]
+    fn test_is_string(){
+        let json_value = from_str("\"dog\"").unwrap();
+        assert!(json_value.is_string());
+    }
+
+    #[test]
+    fn test_as_string(){
+        let json_value = from_str("\"dog\"").unwrap();
+        let json_str = json_value.as_string();
+        let expected_str = &"dog";
+        assert_eq!(json_str, Some(expected_str));
+    }
+
+    #[test]
+    fn test_is_number(){
+        let json_value = from_str("12").unwrap();
+        assert!(json_value.is_number());
+    }
+
+    #[test]
+    fn test_as_number(){
+        let json_value = from_str("12").unwrap();
+        let json_num = json_value.as_number();
+        let expected_num = 12f64;
+        assert!(json_num.is_some() && json_num.unwrap() == expected_num);
+    }
+
+    #[test]
+    fn test_is_boolean(){
+        let json_value = from_str("false").unwrap();
+        assert!(json_value.is_boolean());
+    }
+
+    #[test]
+    fn test_as_boolean(){
+        let json_value = from_str("false").unwrap();
+        let json_bool = json_value.as_boolean();
+        let expected_bool = false;
+        assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool);
+    }
+
+    #[test]
+    fn test_is_null(){
+        let json_value = from_str("null").unwrap();
+        assert!(json_value.is_null());
+    }
+
+    #[test]
+    fn test_as_null(){
+        let json_value = from_str("null").unwrap();
+        let json_null = json_value.as_null();
+        let expected_null = ();
+        assert!(json_null.is_some() && json_null.unwrap() == expected_null);
+    }
+
+    #[test]
+    fn test_encode_hashmap_with_numeric_key() {
+        use std::str::from_utf8;
+        use std::io::Writer;
+        use std::io::MemWriter;
+        use collections::HashMap;
+        let mut hm: HashMap<uint, bool> = HashMap::new();
+        hm.insert(1, true);
+        let mut mem_buf = MemWriter::new();
+        {
+            let mut encoder = Encoder::new(&mut mem_buf as &mut io::Writer);
+            hm.encode(&mut encoder)
+        }
+        let bytes = mem_buf.unwrap();
+        let json_str = from_utf8(bytes).unwrap();
+        match from_str(json_str) {
+            Err(_) => fail!("Unable to parse json_str: {:?}", json_str),
+            _ => {} // it parsed and we are good to go
+        }
+    }
+    #[test]
+    fn test_prettyencode_hashmap_with_numeric_key() {
+        use std::str::from_utf8;
+        use std::io::Writer;
+        use std::io::MemWriter;
+        use collections::HashMap;
+        let mut hm: HashMap<uint, bool> = HashMap::new();
+        hm.insert(1, true);
+        let mut mem_buf = MemWriter::new();
+        {
+            let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut io::Writer);
+            hm.encode(&mut encoder)
+        }
+        let bytes = mem_buf.unwrap();
+        let json_str = from_utf8(bytes).unwrap();
+        match from_str(json_str) {
+            Err(_) => fail!("Unable to parse json_str: {:?}", json_str),
+            _ => {} // it parsed and we are good to go
+        }
+    }
+    #[test]
+    fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
+        use collections::HashMap;
+        use Decodable;
+        let json_str = "{\"1\":true}";
+        let json_obj = match from_str(json_str) {
+            Err(_) => fail!("Unable to parse json_str: {:?}", json_str),
+            Ok(o) => o
+        };
+        let mut decoder = Decoder::new(json_obj);
+        let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder);
+    }
+}
+
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 8a5829da9d6..86e03aae673 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -34,10 +34,31 @@ extern crate collections;
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                           DecoderHelpers, EncoderHelpers};
 
+// FIXME: remove _old.rs files after snapshot
+#[cfg(not(stage0))]
 mod serialize;
+#[cfg(not(stage0))]
 mod collection_impls;
 
 pub mod base64;
+#[cfg(not(stage0))]
 pub mod ebml;
 pub mod hex;
+#[cfg(not(stage0))]
+pub mod json;
+
+#[cfg(stage0)]
+#[path="./serialize_old.rs"]
+pub mod serialize;
+
+#[cfg(stage0)]
+#[path="./collection_impls_old.rs"]
+mod collection_impls;
+
+#[cfg(stage0)]
+#[path="./ebml_old.rs"]
+pub mod ebml;
+
+#[cfg(stage0)]
+#[path="./json_old.rs"]
 pub mod json;
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index a65443653cc..6cda8d9ffb5 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -18,444 +18,465 @@ use std::path;
 use std::rc::Rc;
 use std::slice;
 
-pub trait Encoder {
+pub trait Encoder<E> {
     // Primitive types:
-    fn emit_nil(&mut self);
-    fn emit_uint(&mut self, v: uint);
-    fn emit_u64(&mut self, v: u64);
-    fn emit_u32(&mut self, v: u32);
-    fn emit_u16(&mut self, v: u16);
-    fn emit_u8(&mut self, v: u8);
-    fn emit_int(&mut self, v: int);
-    fn emit_i64(&mut self, v: i64);
-    fn emit_i32(&mut self, v: i32);
-    fn emit_i16(&mut self, v: i16);
-    fn emit_i8(&mut self, v: i8);
-    fn emit_bool(&mut self, v: bool);
-    fn emit_f64(&mut self, v: f64);
-    fn emit_f32(&mut self, v: f32);
-    fn emit_char(&mut self, v: char);
-    fn emit_str(&mut self, v: &str);
+    fn emit_nil(&mut self) -> Result<(), E>;
+    fn emit_uint(&mut self, v: uint) -> Result<(), E>;
+    fn emit_u64(&mut self, v: u64) -> Result<(), E>;
+    fn emit_u32(&mut self, v: u32) -> Result<(), E>;
+    fn emit_u16(&mut self, v: u16) -> Result<(), E>;
+    fn emit_u8(&mut self, v: u8) -> Result<(), E>;
+    fn emit_int(&mut self, v: int) -> Result<(), E>;
+    fn emit_i64(&mut self, v: i64) -> Result<(), E>;
+    fn emit_i32(&mut self, v: i32) -> Result<(), E>;
+    fn emit_i16(&mut self, v: i16) -> Result<(), E>;
+    fn emit_i8(&mut self, v: i8) -> Result<(), E>;
+    fn emit_bool(&mut self, v: bool) -> Result<(), E>;
+    fn emit_f64(&mut self, v: f64) -> Result<(), E>;
+    fn emit_f32(&mut self, v: f32) -> Result<(), E>;
+    fn emit_char(&mut self, v: char) -> Result<(), E>;
+    fn emit_str(&mut self, v: &str) -> Result<(), E>;
 
     // Compound types:
-    fn emit_enum(&mut self, name: &str, f: |&mut Self|);
+    fn emit_enum(&mut self, name: &str, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
     fn emit_enum_variant(&mut self,
                          v_name: &str,
                          v_id: uint,
                          len: uint,
-                         f: |&mut Self|);
-    fn emit_enum_variant_arg(&mut self, a_idx: uint, f: |&mut Self|);
+                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_enum_variant_arg(&mut self,
+                             a_idx: uint,
+                             f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
     fn emit_enum_struct_variant(&mut self,
                                 v_name: &str,
                                 v_id: uint,
                                 len: uint,
-                                f: |&mut Self|);
+                                f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
     fn emit_enum_struct_variant_field(&mut self,
                                       f_name: &str,
                                       f_idx: uint,
-                                      f: |&mut Self|);
+                                      f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
-    fn emit_struct(&mut self, name: &str, len: uint, f: |&mut Self|);
+    fn emit_struct(&mut self,
+                   name: &str,
+                   len: uint,
+                   f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
     fn emit_struct_field(&mut self,
                          f_name: &str,
                          f_idx: uint,
-                         f: |&mut Self|);
+                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
-    fn emit_tuple(&mut self, len: uint, f: |&mut Self|);
-    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self|);
+    fn emit_tuple(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
-    fn emit_tuple_struct(&mut self, name: &str, len: uint, f: |&mut Self|);
-    fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: |&mut Self|);
+    fn emit_tuple_struct(&mut self,
+                         name: &str,
+                         len: uint,
+                         f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_tuple_struct_arg(&mut self,
+                             f_idx: uint,
+                             f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
     // Specialized types:
-    fn emit_option(&mut self, f: |&mut Self|);
-    fn emit_option_none(&mut self);
-    fn emit_option_some(&mut self, f: |&mut Self|);
+    fn emit_option(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_option_none(&mut self) -> Result<(), E>;
+    fn emit_option_some(&mut self, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 
-    fn emit_seq(&mut self, len: uint, f: |this: &mut Self|);
-    fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self|);
+    fn emit_seq(&mut self, len: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self| -> Result<(), E>) -> Result<(), E>;
 
-    fn emit_map(&mut self, len: uint, f: |&mut Self|);
-    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self|);
-    fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self|);
+    fn emit_map(&mut self, len: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
+    fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self| -> Result<(), E>) -> Result<(), E>;
 }
 
-pub trait Decoder {
+pub trait Decoder<E> {
     // Primitive types:
-    fn read_nil(&mut self) -> ();
-    fn read_uint(&mut self) -> uint;
-    fn read_u64(&mut self) -> u64;
-    fn read_u32(&mut self) -> u32;
-    fn read_u16(&mut self) -> u16;
-    fn read_u8(&mut self) -> u8;
-    fn read_int(&mut self) -> int;
-    fn read_i64(&mut self) -> i64;
-    fn read_i32(&mut self) -> i32;
-    fn read_i16(&mut self) -> i16;
-    fn read_i8(&mut self) -> i8;
-    fn read_bool(&mut self) -> bool;
-    fn read_f64(&mut self) -> f64;
-    fn read_f32(&mut self) -> f32;
-    fn read_char(&mut self) -> char;
-    fn read_str(&mut self) -> ~str;
+    fn read_nil(&mut self) -> Result<(), E>;
+    fn read_uint(&mut self) -> Result<uint, E>;
+    fn read_u64(&mut self) -> Result<u64, E>;
+    fn read_u32(&mut self) -> Result<u32, E>;
+    fn read_u16(&mut self) -> Result<u16, E>;
+    fn read_u8(&mut self) -> Result<u8, E>;
+    fn read_int(&mut self) -> Result<int, E>;
+    fn read_i64(&mut self) -> Result<i64, E>;
+    fn read_i32(&mut self) -> Result<i32, E>;
+    fn read_i16(&mut self) -> Result<i16, E>;
+    fn read_i8(&mut self) -> Result<i8, E>;
+    fn read_bool(&mut self) -> Result<bool, E>;
+    fn read_f64(&mut self) -> Result<f64, E>;
+    fn read_f32(&mut self) -> Result<f32, E>;
+    fn read_char(&mut self) -> Result<char, E>;
+    fn read_str(&mut self) -> Result<~str, E>;
 
     // Compound types:
-    fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> T) -> T;
+    fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
 
     fn read_enum_variant<T>(&mut self,
                             names: &[&str],
-                            f: |&mut Self, uint| -> T)
-                            -> T;
+                            f: |&mut Self, uint| -> Result<T, E>)
+                            -> Result<T, E>;
     fn read_enum_variant_arg<T>(&mut self,
                                 a_idx: uint,
-                                f: |&mut Self| -> T)
-                                -> T;
+                                f: |&mut Self| -> Result<T, E>)
+                                -> Result<T, E>;
 
     fn read_enum_struct_variant<T>(&mut self,
                                    names: &[&str],
-                                   f: |&mut Self, uint| -> T)
-                                   -> T;
+                                   f: |&mut Self, uint| -> Result<T, E>)
+                                   -> Result<T, E>;
     fn read_enum_struct_variant_field<T>(&mut self,
                                          &f_name: &str,
                                          f_idx: uint,
-                                         f: |&mut Self| -> T)
-                                         -> T;
+                                         f: |&mut Self| -> Result<T, E>)
+                                         -> Result<T, E>;
 
-    fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> T)
-                      -> T;
+    fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> Result<T, E>)
+                      -> Result<T, E>;
     fn read_struct_field<T>(&mut self,
                             f_name: &str,
                             f_idx: uint,
-                            f: |&mut Self| -> T)
-                            -> T;
+                            f: |&mut Self| -> Result<T, E>)
+                            -> Result<T, E>;
 
-    fn read_tuple<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
-    fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> T) -> T;
+    fn read_tuple<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>;
+    fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
 
     fn read_tuple_struct<T>(&mut self,
                             s_name: &str,
-                            f: |&mut Self, uint| -> T)
-                            -> T;
+                            f: |&mut Self, uint| -> Result<T, E>)
+                            -> Result<T, E>;
     fn read_tuple_struct_arg<T>(&mut self,
                                 a_idx: uint,
-                                f: |&mut Self| -> T)
-                                -> T;
+                                f: |&mut Self| -> Result<T, E>)
+                                -> Result<T, E>;
 
     // Specialized types:
-    fn read_option<T>(&mut self, f: |&mut Self, bool| -> T) -> T;
+    fn read_option<T>(&mut self, f: |&mut Self, bool| -> Result<T, E>) -> Result<T, E>;
 
-    fn read_seq<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
-    fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
+    fn read_seq<T>(&mut self, f: |&mut Self, uint| -> Result<T, E>) -> Result<T, E>;
+    fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> Result<T, E>) -> Result<T, E>;
 
-    fn read_map<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
-    fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
-    fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
+    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>;
 }
 
-pub trait Encodable<S:Encoder> {
-    fn encode(&self, s: &mut S);
+pub trait Encodable<S:Encoder<E>, E> {
+    fn encode(&self, s: &mut S) -> Result<(), E>;
 }
 
-pub trait Decodable<D:Decoder> {
-    fn decode(d: &mut D) -> Self;
+pub trait Decodable<D:Decoder<E>, E> {
+    fn decode(d: &mut D) -> Result<Self, E>;
 }
 
-impl<S:Encoder> Encodable<S> for uint {
-    fn encode(&self, s: &mut S) {
+macro_rules! try ( ($e:expr) => (
+    match $e { Ok(v) => v, Err(e) => return Err(e) }
+))
+
+impl<E, S:Encoder<E>> Encodable<S, E> for uint {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_uint(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for uint {
-    fn decode(d: &mut D) -> uint {
+impl<E, D:Decoder<E>> Decodable<D, E> for uint {
+    fn decode(d: &mut D) -> Result<uint, E> {
         d.read_uint()
     }
 }
 
-impl<S:Encoder> Encodable<S> for u8 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for u8 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_u8(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for u8 {
-    fn decode(d: &mut D) -> u8 {
+impl<E, D:Decoder<E>> Decodable<D, E> for u8 {
+    fn decode(d: &mut D) -> Result<u8, E> {
         d.read_u8()
     }
 }
 
-impl<S:Encoder> Encodable<S> for u16 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for u16 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_u16(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for u16 {
-    fn decode(d: &mut D) -> u16 {
+impl<E, D:Decoder<E>> Decodable<D, E> for u16 {
+    fn decode(d: &mut D) -> Result<u16, E> {
         d.read_u16()
     }
 }
 
-impl<S:Encoder> Encodable<S> for u32 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for u32 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_u32(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for u32 {
-    fn decode(d: &mut D) -> u32 {
+impl<E, D:Decoder<E>> Decodable<D, E> for u32 {
+    fn decode(d: &mut D) -> Result<u32, E> {
         d.read_u32()
     }
 }
 
-impl<S:Encoder> Encodable<S> for u64 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for u64 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_u64(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for u64 {
-    fn decode(d: &mut D) -> u64 {
+impl<E, D:Decoder<E>> Decodable<D, E> for u64 {
+    fn decode(d: &mut D) -> Result<u64, E> {
         d.read_u64()
     }
 }
 
-impl<S:Encoder> Encodable<S> for int {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for int {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_int(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for int {
-    fn decode(d: &mut D) -> int {
+impl<E, D:Decoder<E>> Decodable<D, E> for int {
+    fn decode(d: &mut D) -> Result<int, E> {
         d.read_int()
     }
 }
 
-impl<S:Encoder> Encodable<S> for i8 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for i8 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_i8(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for i8 {
-    fn decode(d: &mut D) -> i8 {
+impl<E, D:Decoder<E>> Decodable<D, E> for i8 {
+    fn decode(d: &mut D) -> Result<i8, E> {
         d.read_i8()
     }
 }
 
-impl<S:Encoder> Encodable<S> for i16 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for i16 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_i16(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for i16 {
-    fn decode(d: &mut D) -> i16 {
+impl<E, D:Decoder<E>> Decodable<D, E> for i16 {
+    fn decode(d: &mut D) -> Result<i16, E> {
         d.read_i16()
     }
 }
 
-impl<S:Encoder> Encodable<S> for i32 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for i32 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_i32(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for i32 {
-    fn decode(d: &mut D) -> i32 {
+impl<E, D:Decoder<E>> Decodable<D, E> for i32 {
+    fn decode(d: &mut D) -> Result<i32, E> {
         d.read_i32()
     }
 }
 
-impl<S:Encoder> Encodable<S> for i64 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for i64 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_i64(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for i64 {
-    fn decode(d: &mut D) -> i64 {
+impl<E, D:Decoder<E>> Decodable<D, E> for i64 {
+    fn decode(d: &mut D) -> Result<i64, E> {
         d.read_i64()
     }
 }
 
-impl<'a, S:Encoder> Encodable<S> for &'a str {
-    fn encode(&self, s: &mut S) {
+impl<'a, E, S:Encoder<E>> Encodable<S, E> for &'a str {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_str(*self)
     }
 }
 
-impl<S:Encoder> Encodable<S> for ~str {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for ~str {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_str(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for ~str {
-    fn decode(d: &mut D) -> ~str {
+impl<E, D:Decoder<E>> Decodable<D, E> for ~str {
+    fn decode(d: &mut D) -> Result<~str, E> {
         d.read_str()
     }
 }
 
-impl<S:Encoder> Encodable<S> for f32 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for f32 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_f32(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for f32 {
-    fn decode(d: &mut D) -> f32 {
+impl<E, D:Decoder<E>> Decodable<D, E> for f32 {
+    fn decode(d: &mut D) -> Result<f32, E> {
         d.read_f32()
     }
 }
 
-impl<S:Encoder> Encodable<S> for f64 {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for f64 {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_f64(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for f64 {
-    fn decode(d: &mut D) -> f64 {
+impl<E, D:Decoder<E>> Decodable<D, E> for f64 {
+    fn decode(d: &mut D) -> Result<f64, E> {
         d.read_f64()
     }
 }
 
-impl<S:Encoder> Encodable<S> for bool {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for bool {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_bool(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for bool {
-    fn decode(d: &mut D) -> bool {
+impl<E, D:Decoder<E>> Decodable<D, E> for bool {
+    fn decode(d: &mut D) -> Result<bool, E> {
         d.read_bool()
     }
 }
 
-impl<S:Encoder> Encodable<S> for char {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for char {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_char(*self)
     }
 }
 
-impl<D:Decoder> Decodable<D> for char {
-    fn decode(d: &mut D) -> char {
+impl<E, D:Decoder<E>> Decodable<D, E> for char {
+    fn decode(d: &mut D) -> Result<char, E> {
         d.read_char()
     }
 }
 
-impl<S:Encoder> Encodable<S> for () {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>> Encodable<S, E> for () {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_nil()
     }
 }
 
-impl<D:Decoder> Decodable<D> for () {
-    fn decode(d: &mut D) -> () {
+impl<E, D:Decoder<E>> Decodable<D, E> for () {
+    fn decode(d: &mut D) -> Result<(), E> {
         d.read_nil()
     }
 }
 
-impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a T {
-    fn encode(&self, s: &mut S) {
+impl<'a, E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for &'a T {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for ~T {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T {
-    fn decode(d: &mut D) -> ~T {
-        ~Decodable::decode(d)
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for ~T {
+    fn decode(d: &mut D) -> Result<~T, E> {
+        Ok(~try!(Decodable::decode(d)))
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for @T {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for Rc<T> {
     #[inline]
-    fn encode(&self, s: &mut S) {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for Rc<T> {
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Rc<T> {
     #[inline]
-    fn decode(d: &mut D) -> Rc<T> {
-        Rc::new(Decodable::decode(d))
+    fn decode(d: &mut D) -> Result<Rc<T>, E> {
+        Ok(Rc::new(try!(Decodable::decode(d))))
     }
 }
 
-impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @T {
-    fn decode(d: &mut D) -> @T {
-        @Decodable::decode(d)
+impl<E, D:Decoder<E>,T:Decodable<D, E> + 'static> Decodable<D, E> for @T {
+    fn decode(d: &mut D) -> Result<@T, E> {
+        Ok(@try!(Decodable::decode(d)))
     }
 }
 
-impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a [T] {
-    fn encode(&self, s: &mut S) {
+impl<'a, E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for &'a [T] {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
-                s.emit_seq_elt(i, |s| e.encode(s))
+                try!(s.emit_seq_elt(i, |s| e.encode(s)))
             }
+            Ok(())
         })
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for ~[T] {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
-                s.emit_seq_elt(i, |s| e.encode(s))
+                try!(s.emit_seq_elt(i, |s| e.encode(s)))
             }
+            Ok(())
         })
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
-    fn decode(d: &mut D) -> ~[T] {
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for ~[T] {
+    fn decode(d: &mut D) -> Result<~[T], E> {
         d.read_seq(|d, len| {
-            slice::from_fn(len, |i| {
-                d.read_seq_elt(i, |d| Decodable::decode(d))
-            })
+            let mut v: ~[T] = slice::with_capacity(len);
+            for i in range(0, len) {
+                v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
+            }
+            Ok(v)
         })
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for Vec<T> {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for Vec<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
-                s.emit_seq_elt(i, |s| e.encode(s))
+                try!(s.emit_seq_elt(i, |s| e.encode(s)))
             }
+            Ok(())
         })
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for Vec<T> {
-    fn decode(d: &mut D) -> Vec<T> {
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Vec<T> {
+    fn decode(d: &mut D) -> Result<Vec<T>, E> {
         d.read_seq(|d, len| {
-            Vec::from_fn(len, |i| {
-                d.read_seq_elt(i, |d| Decodable::decode(d))
-            })
+            let mut v = Vec::with_capacity(len);
+            for i in range(0, len) {
+                v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
+            }
+            Ok(v)
         })
     }
 }
 
-impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
-    fn encode(&self, s: &mut S) {
+impl<E, S:Encoder<E>,T:Encodable<S, E>> Encodable<S, E> for Option<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
         s.emit_option(|s| {
             match *self {
                 None => s.emit_option_none(),
@@ -465,13 +486,13 @@ impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
-    fn decode(d: &mut D) -> Option<T> {
+impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for Option<T> {
+    fn decode(d: &mut D) -> Result<Option<T>, E> {
         d.read_option(|d, b| {
             if b {
-                Some(Decodable::decode(d))
+                Ok(Some(try!(Decodable::decode(d))))
             } else {
-                None
+                Ok(None)
             }
         })
     }
@@ -482,30 +503,31 @@ macro_rules! peel(($name:ident, $($other:ident,)*) => (tuple!($($other,)*)))
 macro_rules! tuple (
     () => ();
     ( $($name:ident,)+ ) => (
-        impl<D:Decoder,$($name:Decodable<D>),*> Decodable<D> for ($($name,)*) {
+        impl<E, D:Decoder<E>,$($name:Decodable<D, E>),*> Decodable<D,E> for ($($name,)*) {
             #[allow(uppercase_variables)]
-            fn decode(d: &mut D) -> ($($name,)*) {
+            fn decode(d: &mut D) -> Result<($($name,)*), E> {
                 d.read_tuple(|d, amt| {
                     let mut i = 0;
-                    let ret = ($(d.read_tuple_arg({ i+=1; i-1 }, |d| -> $name {
+                    let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name,E> {
                         Decodable::decode(d)
-                    }),)*);
+                    })),)*);
                     assert!(amt == i,
                             "expected tuple of length `{}`, found tuple \
                              of length `{}`", i, amt);
-                    return ret;
+                    return Ok(ret);
                 })
             }
         }
-        impl<S:Encoder,$($name:Encodable<S>),*> Encodable<S> for ($($name,)*) {
+        impl<E, S:Encoder<E>,$($name:Encodable<S, E>),*> Encodable<S, E> for ($($name,)*) {
             #[allow(uppercase_variables)]
-            fn encode(&self, s: &mut S) {
+            fn encode(&self, s: &mut S) -> Result<(), E> {
                 let ($(ref $name,)*) = *self;
                 let mut n = 0;
                 $(let $name = $name; n += 1;)*
                 s.emit_tuple(n, |s| {
                     let mut i = 0;
-                    $(s.emit_seq_elt({ i+=1; i-1 }, |s| $name.encode(s));)*
+                    $(try!(s.emit_seq_elt({ i+=1; i-1 }, |s| $name.encode(s)));)*
+                    Ok(())
                 })
             }
         }
@@ -515,29 +537,29 @@ macro_rules! tuple (
 
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
-impl<E: Encoder> Encodable<E> for path::posix::Path {
-    fn encode(&self, e: &mut E) {
+impl<E, S: Encoder<E>> Encodable<S, E> for path::posix::Path {
+    fn encode(&self, e: &mut S) -> Result<(), E> {
         self.as_vec().encode(e)
     }
 }
 
-impl<D: Decoder> Decodable<D> for path::posix::Path {
-    fn decode(d: &mut D) -> path::posix::Path {
-        let bytes: ~[u8] = Decodable::decode(d);
-        path::posix::Path::new(bytes)
+impl<E, D: Decoder<E>> Decodable<D, E> for path::posix::Path {
+    fn decode(d: &mut D) -> Result<path::posix::Path, E> {
+        let bytes: ~[u8] = try!(Decodable::decode(d));
+        Ok(path::posix::Path::new(bytes))
     }
 }
 
-impl<E: Encoder> Encodable<E> for path::windows::Path {
-    fn encode(&self, e: &mut E) {
+impl<E, S: Encoder<E>> Encodable<S, E> for path::windows::Path {
+    fn encode(&self, e: &mut S) -> Result<(), E> {
         self.as_vec().encode(e)
     }
 }
 
-impl<D: Decoder> Decodable<D> for path::windows::Path {
-    fn decode(d: &mut D) -> path::windows::Path {
-        let bytes: ~[u8] = Decodable::decode(d);
-        path::windows::Path::new(bytes)
+impl<E, D: Decoder<E>> Decodable<D, E> for path::windows::Path {
+    fn decode(d: &mut D) -> Result<path::windows::Path, E> {
+        let bytes: ~[u8] = try!(Decodable::decode(d));
+        Ok(path::windows::Path::new(bytes))
     }
 }
 
@@ -546,32 +568,37 @@ impl<D: Decoder> Decodable<D> for path::windows::Path {
 //
 // In some cases, these should eventually be coded as traits.
 
-pub trait EncoderHelpers {
-    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut Self, v: &T|);
+pub trait EncoderHelpers<E> {
+    fn emit_from_vec<T>(&mut self,
+                        v: &[T],
+                        f: |&mut Self, v: &T| -> Result<(), E>) -> Result<(), E>;
 }
 
-impl<S:Encoder> EncoderHelpers for S {
-    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T|) {
+impl<E, S:Encoder<E>> EncoderHelpers<E> for S {
+    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T| -> Result<(), E>) -> Result<(), E> {
         self.emit_seq(v.len(), |this| {
             for (i, e) in v.iter().enumerate() {
-                this.emit_seq_elt(i, |this| {
+                try!(this.emit_seq_elt(i, |this| {
                     f(this, e)
-                })
+                }));
             }
+            Ok(())
         })
     }
 }
 
-pub trait DecoderHelpers {
-    fn read_to_vec<T>(&mut self, f: |&mut Self| -> T) -> ~[T];
+pub trait DecoderHelpers<E> {
+    fn read_to_vec<T>(&mut self, f: |&mut Self| -> Result<T, E>) -> Result<~[T], E>;
 }
 
-impl<D:Decoder> DecoderHelpers for D {
-    fn read_to_vec<T>(&mut self, f: |&mut D| -> T) -> ~[T] {
+impl<E, D:Decoder<E>> DecoderHelpers<E> for D {
+    fn read_to_vec<T>(&mut self, f: |&mut D| -> Result<T, E>) -> Result<~[T], E> {
         self.read_seq(|this, len| {
-            slice::from_fn(len, |i| {
-                this.read_seq_elt(i, |this| f(this))
-            })
+            let mut v = slice::with_capacity(len);
+            for i in range(0, len) {
+                v.push(try!(this.read_seq_elt(i, |this| f(this))));
+            }
+            Ok(v)
         })
     }
 }
diff --git a/src/libserialize/serialize_old.rs b/src/libserialize/serialize_old.rs
new file mode 100644
index 00000000000..4043cbe65fe
--- /dev/null
+++ b/src/libserialize/serialize_old.rs
@@ -0,0 +1,688 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Support code for encoding and decoding types.
+
+/*
+Core encoding and decoding interfaces.
+*/
+
+use std::path;
+use std::rc::Rc;
+use std::slice;
+
+pub trait Encoder {
+    // Primitive types:
+    fn emit_nil(&mut self);
+    fn emit_uint(&mut self, v: uint);
+    fn emit_u64(&mut self, v: u64);
+    fn emit_u32(&mut self, v: u32);
+    fn emit_u16(&mut self, v: u16);
+    fn emit_u8(&mut self, v: u8);
+    fn emit_int(&mut self, v: int);
+    fn emit_i64(&mut self, v: i64);
+    fn emit_i32(&mut self, v: i32);
+    fn emit_i16(&mut self, v: i16);
+    fn emit_i8(&mut self, v: i8);
+    fn emit_bool(&mut self, v: bool);
+    fn emit_f64(&mut self, v: f64);
+    fn emit_f32(&mut self, v: f32);
+    fn emit_char(&mut self, v: char);
+    fn emit_str(&mut self, v: &str);
+
+    // Compound types:
+    fn emit_enum(&mut self, name: &str, f: |&mut Self|);
+
+    fn emit_enum_variant(&mut self,
+                         v_name: &str,
+                         v_id: uint,
+                         len: uint,
+                         f: |&mut Self|);
+    fn emit_enum_variant_arg(&mut self, a_idx: uint, f: |&mut Self|);
+
+    fn emit_enum_struct_variant(&mut self,
+                                v_name: &str,
+                                v_id: uint,
+                                len: uint,
+                                f: |&mut Self|);
+    fn emit_enum_struct_variant_field(&mut self,
+                                      f_name: &str,
+                                      f_idx: uint,
+                                      f: |&mut Self|);
+
+    fn emit_struct(&mut self, name: &str, len: uint, f: |&mut Self|);
+    fn emit_struct_field(&mut self,
+                         f_name: &str,
+                         f_idx: uint,
+                         f: |&mut Self|);
+
+    fn emit_tuple(&mut self, len: uint, f: |&mut Self|);
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Self|);
+
+    fn emit_tuple_struct(&mut self, name: &str, len: uint, f: |&mut Self|);
+    fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: |&mut Self|);
+
+    // Specialized types:
+    fn emit_option(&mut self, f: |&mut Self|);
+    fn emit_option_none(&mut self);
+    fn emit_option_some(&mut self, f: |&mut Self|);
+
+    fn emit_seq(&mut self, len: uint, f: |this: &mut Self|);
+    fn emit_seq_elt(&mut self, idx: uint, f: |this: &mut Self|);
+
+    fn emit_map(&mut self, len: uint, f: |&mut Self|);
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Self|);
+    fn emit_map_elt_val(&mut self, idx: uint, f: |&mut Self|);
+}
+
+pub trait Decoder {
+    // Primitive types:
+    fn read_nil(&mut self) -> ();
+    fn read_uint(&mut self) -> uint;
+    fn read_u64(&mut self) -> u64;
+    fn read_u32(&mut self) -> u32;
+    fn read_u16(&mut self) -> u16;
+    fn read_u8(&mut self) -> u8;
+    fn read_int(&mut self) -> int;
+    fn read_i64(&mut self) -> i64;
+    fn read_i32(&mut self) -> i32;
+    fn read_i16(&mut self) -> i16;
+    fn read_i8(&mut self) -> i8;
+    fn read_bool(&mut self) -> bool;
+    fn read_f64(&mut self) -> f64;
+    fn read_f32(&mut self) -> f32;
+    fn read_char(&mut self) -> char;
+    fn read_str(&mut self) -> ~str;
+
+    // Compound types:
+    fn read_enum<T>(&mut self, name: &str, f: |&mut Self| -> T) -> T;
+
+    fn read_enum_variant<T>(&mut self,
+                            names: &[&str],
+                            f: |&mut Self, uint| -> T)
+                            -> T;
+    fn read_enum_variant_arg<T>(&mut self,
+                                a_idx: uint,
+                                f: |&mut Self| -> T)
+                                -> T;
+
+    fn read_enum_struct_variant<T>(&mut self,
+                                   names: &[&str],
+                                   f: |&mut Self, uint| -> T)
+                                   -> T;
+    fn read_enum_struct_variant_field<T>(&mut self,
+                                         &f_name: &str,
+                                         f_idx: uint,
+                                         f: |&mut Self| -> T)
+                                         -> T;
+
+    fn read_struct<T>(&mut self, s_name: &str, len: uint, f: |&mut Self| -> T)
+                      -> T;
+    fn read_struct_field<T>(&mut self,
+                            f_name: &str,
+                            f_idx: uint,
+                            f: |&mut Self| -> T)
+                            -> T;
+
+    fn read_tuple<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
+    fn read_tuple_arg<T>(&mut self, a_idx: uint, f: |&mut Self| -> T) -> T;
+
+    fn read_tuple_struct<T>(&mut self,
+                            s_name: &str,
+                            f: |&mut Self, uint| -> T)
+                            -> T;
+    fn read_tuple_struct_arg<T>(&mut self,
+                                a_idx: uint,
+                                f: |&mut Self| -> T)
+                                -> T;
+
+    // Specialized types:
+    fn read_option<T>(&mut self, f: |&mut Self, bool| -> T) -> T;
+
+    fn read_seq<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
+    fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
+
+    fn read_map<T>(&mut self, f: |&mut Self, uint| -> T) -> T;
+    fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
+    fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Self| -> T) -> T;
+}
+
+pub trait Encodable<S:Encoder> {
+    fn encode(&self, s: &mut S);
+}
+
+pub trait Decodable<D:Decoder> {
+    fn decode(d: &mut D) -> Self;
+}
+
+impl<S:Encoder> Encodable<S> for uint {
+    fn encode(&self, s: &mut S) {
+        s.emit_uint(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for uint {
+    fn decode(d: &mut D) -> uint {
+        d.read_uint()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for u8 {
+    fn encode(&self, s: &mut S) {
+        s.emit_u8(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for u8 {
+    fn decode(d: &mut D) -> u8 {
+        d.read_u8()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for u16 {
+    fn encode(&self, s: &mut S) {
+        s.emit_u16(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for u16 {
+    fn decode(d: &mut D) -> u16 {
+        d.read_u16()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for u32 {
+    fn encode(&self, s: &mut S) {
+        s.emit_u32(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for u32 {
+    fn decode(d: &mut D) -> u32 {
+        d.read_u32()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for u64 {
+    fn encode(&self, s: &mut S) {
+        s.emit_u64(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for u64 {
+    fn decode(d: &mut D) -> u64 {
+        d.read_u64()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for int {
+    fn encode(&self, s: &mut S) {
+        s.emit_int(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for int {
+    fn decode(d: &mut D) -> int {
+        d.read_int()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for i8 {
+    fn encode(&self, s: &mut S) {
+        s.emit_i8(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for i8 {
+    fn decode(d: &mut D) -> i8 {
+        d.read_i8()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for i16 {
+    fn encode(&self, s: &mut S) {
+        s.emit_i16(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for i16 {
+    fn decode(d: &mut D) -> i16 {
+        d.read_i16()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for i32 {
+    fn encode(&self, s: &mut S) {
+        s.emit_i32(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for i32 {
+    fn decode(d: &mut D) -> i32 {
+        d.read_i32()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for i64 {
+    fn encode(&self, s: &mut S) {
+        s.emit_i64(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for i64 {
+    fn decode(d: &mut D) -> i64 {
+        d.read_i64()
+    }
+}
+
+impl<'a, S:Encoder> Encodable<S> for &'a str {
+    fn encode(&self, s: &mut S) {
+        s.emit_str(*self)
+    }
+}
+
+impl<S:Encoder> Encodable<S> for ~str {
+    fn encode(&self, s: &mut S) {
+        s.emit_str(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for ~str {
+    fn decode(d: &mut D) -> ~str {
+        d.read_str()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for f32 {
+    fn encode(&self, s: &mut S) {
+        s.emit_f32(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for f32 {
+    fn decode(d: &mut D) -> f32 {
+        d.read_f32()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for f64 {
+    fn encode(&self, s: &mut S) {
+        s.emit_f64(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for f64 {
+    fn decode(d: &mut D) -> f64 {
+        d.read_f64()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for bool {
+    fn encode(&self, s: &mut S) {
+        s.emit_bool(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for bool {
+    fn decode(d: &mut D) -> bool {
+        d.read_bool()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for char {
+    fn encode(&self, s: &mut S) {
+        s.emit_char(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for char {
+    fn decode(d: &mut D) -> char {
+        d.read_char()
+    }
+}
+
+impl<S:Encoder> Encodable<S> for () {
+    fn encode(&self, s: &mut S) {
+        s.emit_nil()
+    }
+}
+
+impl<D:Decoder> Decodable<D> for () {
+    fn decode(d: &mut D) -> () {
+        d.read_nil()
+    }
+}
+
+impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a T {
+    fn encode(&self, s: &mut S) {
+        (**self).encode(s)
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~T {
+    fn encode(&self, s: &mut S) {
+        (**self).encode(s)
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~T {
+    fn decode(d: &mut D) -> ~T {
+        ~Decodable::decode(d)
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for @T {
+    fn encode(&self, s: &mut S) {
+        (**self).encode(s)
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for Rc<T> {
+    #[inline]
+    fn encode(&self, s: &mut S) {
+        (**self).encode(s)
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for Rc<T> {
+    #[inline]
+    fn decode(d: &mut D) -> Rc<T> {
+        Rc::new(Decodable::decode(d))
+    }
+}
+
+impl<D:Decoder,T:Decodable<D> + 'static> Decodable<D> for @T {
+    fn decode(d: &mut D) -> @T {
+        @Decodable::decode(d)
+    }
+}
+
+impl<'a, S:Encoder,T:Encodable<S>> Encodable<S> for &'a [T] {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s))
+            }
+        })
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s))
+            }
+        })
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
+    fn decode(d: &mut D) -> ~[T] {
+        d.read_seq(|d, len| {
+            slice::from_fn(len, |i| {
+                d.read_seq_elt(i, |d| Decodable::decode(d))
+            })
+        })
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for Vec<T> {
+    fn encode(&self, s: &mut S) {
+        s.emit_seq(self.len(), |s| {
+            for (i, e) in self.iter().enumerate() {
+                s.emit_seq_elt(i, |s| e.encode(s))
+            }
+        })
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for Vec<T> {
+    fn decode(d: &mut D) -> Vec<T> {
+        d.read_seq(|d, len| {
+            Vec::from_fn(len, |i| {
+                d.read_seq_elt(i, |d| Decodable::decode(d))
+            })
+        })
+    }
+}
+
+impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> {
+    fn encode(&self, s: &mut S) {
+        s.emit_option(|s| {
+            match *self {
+                None => s.emit_option_none(),
+                Some(ref v) => s.emit_option_some(|s| v.encode(s)),
+            }
+        })
+    }
+}
+
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for Option<T> {
+    fn decode(d: &mut D) -> Option<T> {
+        d.read_option(|d, b| {
+            if b {
+                Some(Decodable::decode(d))
+            } else {
+                None
+            }
+        })
+    }
+}
+
+impl<S:Encoder,T0:Encodable<S>,T1:Encodable<S>> Encodable<S> for (T0, T1) {
+    fn encode(&self, s: &mut S) {
+        match *self {
+            (ref t0, ref t1) => {
+                s.emit_seq(2, |s| {
+                    s.emit_seq_elt(0, |s| t0.encode(s));
+                    s.emit_seq_elt(1, |s| t1.encode(s));
+                })
+            }
+        }
+    }
+}
+
+impl<D:Decoder,T0:Decodable<D>,T1:Decodable<D>> Decodable<D> for (T0, T1) {
+    fn decode(d: &mut D) -> (T0, T1) {
+        d.read_seq(|d, len| {
+            assert_eq!(len, 2);
+            (
+                d.read_seq_elt(0, |d| Decodable::decode(d)),
+                d.read_seq_elt(1, |d| Decodable::decode(d))
+            )
+        })
+    }
+}
+
+impl<
+    S: Encoder,
+    T0: Encodable<S>,
+    T1: Encodable<S>,
+    T2: Encodable<S>
+> Encodable<S> for (T0, T1, T2) {
+    fn encode(&self, s: &mut S) {
+        match *self {
+            (ref t0, ref t1, ref t2) => {
+                s.emit_seq(3, |s| {
+                    s.emit_seq_elt(0, |s| t0.encode(s));
+                    s.emit_seq_elt(1, |s| t1.encode(s));
+                    s.emit_seq_elt(2, |s| t2.encode(s));
+                })
+            }
+        }
+    }
+}
+
+impl<
+    D: Decoder,
+    T0: Decodable<D>,
+    T1: Decodable<D>,
+    T2: Decodable<D>
+> Decodable<D> for (T0, T1, T2) {
+    fn decode(d: &mut D) -> (T0, T1, T2) {
+        d.read_seq(|d, len| {
+            assert_eq!(len, 3);
+            (
+                d.read_seq_elt(0, |d| Decodable::decode(d)),
+                d.read_seq_elt(1, |d| Decodable::decode(d)),
+                d.read_seq_elt(2, |d| Decodable::decode(d))
+            )
+        })
+    }
+}
+
+impl<
+    S: Encoder,
+    T0: Encodable<S>,
+    T1: Encodable<S>,
+    T2: Encodable<S>,
+    T3: Encodable<S>
+> Encodable<S> for (T0, T1, T2, T3) {
+    fn encode(&self, s: &mut S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3) => {
+                s.emit_seq(4, |s| {
+                    s.emit_seq_elt(0, |s| t0.encode(s));
+                    s.emit_seq_elt(1, |s| t1.encode(s));
+                    s.emit_seq_elt(2, |s| t2.encode(s));
+                    s.emit_seq_elt(3, |s| t3.encode(s));
+                })
+            }
+        }
+    }
+}
+
+impl<
+    D: Decoder,
+    T0: Decodable<D>,
+    T1: Decodable<D>,
+    T2: Decodable<D>,
+    T3: Decodable<D>
+> Decodable<D> for (T0, T1, T2, T3) {
+    fn decode(d: &mut D) -> (T0, T1, T2, T3) {
+        d.read_seq(|d, len| {
+            assert_eq!(len, 4);
+            (
+                d.read_seq_elt(0, |d| Decodable::decode(d)),
+                d.read_seq_elt(1, |d| Decodable::decode(d)),
+                d.read_seq_elt(2, |d| Decodable::decode(d)),
+                d.read_seq_elt(3, |d| Decodable::decode(d))
+            )
+        })
+    }
+}
+
+impl<
+    S: Encoder,
+    T0: Encodable<S>,
+    T1: Encodable<S>,
+    T2: Encodable<S>,
+    T3: Encodable<S>,
+    T4: Encodable<S>
+> Encodable<S> for (T0, T1, T2, T3, T4) {
+    fn encode(&self, s: &mut S) {
+        match *self {
+            (ref t0, ref t1, ref t2, ref t3, ref t4) => {
+                s.emit_seq(5, |s| {
+                    s.emit_seq_elt(0, |s| t0.encode(s));
+                    s.emit_seq_elt(1, |s| t1.encode(s));
+                    s.emit_seq_elt(2, |s| t2.encode(s));
+                    s.emit_seq_elt(3, |s| t3.encode(s));
+                    s.emit_seq_elt(4, |s| t4.encode(s));
+                })
+            }
+        }
+    }
+}
+
+impl<
+    D: Decoder,
+    T0: Decodable<D>,
+    T1: Decodable<D>,
+    T2: Decodable<D>,
+    T3: Decodable<D>,
+    T4: Decodable<D>
+> Decodable<D> for (T0, T1, T2, T3, T4) {
+    fn decode(d: &mut D) -> (T0, T1, T2, T3, T4) {
+        d.read_seq(|d, len| {
+            assert_eq!(len, 5);
+            (
+                d.read_seq_elt(0, |d| Decodable::decode(d)),
+                d.read_seq_elt(1, |d| Decodable::decode(d)),
+                d.read_seq_elt(2, |d| Decodable::decode(d)),
+                d.read_seq_elt(3, |d| Decodable::decode(d)),
+                d.read_seq_elt(4, |d| Decodable::decode(d))
+            )
+        })
+    }
+}
+
+impl<E: Encoder> Encodable<E> for path::posix::Path {
+    fn encode(&self, e: &mut E) {
+        self.as_vec().encode(e)
+    }
+}
+
+impl<D: Decoder> Decodable<D> for path::posix::Path {
+    fn decode(d: &mut D) -> path::posix::Path {
+        let bytes: ~[u8] = Decodable::decode(d);
+        path::posix::Path::new(bytes)
+    }
+}
+
+impl<E: Encoder> Encodable<E> for path::windows::Path {
+    fn encode(&self, e: &mut E) {
+        self.as_vec().encode(e)
+    }
+}
+
+impl<D: Decoder> Decodable<D> for path::windows::Path {
+    fn decode(d: &mut D) -> path::windows::Path {
+        let bytes: ~[u8] = Decodable::decode(d);
+        path::windows::Path::new(bytes)
+    }
+}
+
+// ___________________________________________________________________________
+// Helper routines
+//
+// In some cases, these should eventually be coded as traits.
+
+pub trait EncoderHelpers {
+    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut Self, v: &T|);
+}
+
+impl<S:Encoder> EncoderHelpers for S {
+    fn emit_from_vec<T>(&mut self, v: &[T], f: |&mut S, &T|) {
+        self.emit_seq(v.len(), |this| {
+            for (i, e) in v.iter().enumerate() {
+                this.emit_seq_elt(i, |this| {
+                    f(this, e)
+                })
+            }
+        })
+    }
+}
+
+pub trait DecoderHelpers {
+    fn read_to_vec<T>(&mut self, f: |&mut Self| -> T) -> ~[T];
+}
+
+impl<D:Decoder> DecoderHelpers for D {
+    fn read_to_vec<T>(&mut self, f: |&mut D| -> T) -> ~[T] {
+        self.read_seq(|this, len| {
+            slice::from_fn(len, |i| {
+                this.read_seq_elt(i, |this| f(this))
+            })
+        })
+    }
+}
+