about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2012-09-26 21:35:13 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-10-01 20:43:59 -0700
commit81423a3866fb6cd4cadd28ed49273d7e22d48c17 (patch)
tree28bbbf3b65f82dc7554c8b7371ed46f8a381c75e /src/libstd
parent0a950f394dbe3275c4879dc1f26f78a096f93e28 (diff)
Add deserializable and more types to serialization2
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ebml2.rs93
-rw-r--r--src/libstd/json.rs176
-rw-r--r--src/libstd/prettyprint2.rs63
-rw-r--r--src/libstd/serialization2.rs208
4 files changed, 411 insertions, 129 deletions
diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs
index 10653760368..3ed6426b829 100644
--- a/src/libstd/ebml2.rs
+++ b/src/libstd/ebml2.rs
@@ -384,7 +384,25 @@ impl Serializer: serialization2::Serializer {
         fail ~"Unimplemented: serializing a float";
     }
 
-    fn emit_str(&self, v: &str) { self.wr_tagged_str(EsStr as uint, v) }
+    fn emit_char(&self, _v: char) {
+        fail ~"Unimplemented: serializing a char";
+    }
+
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr_tagged_str(EsStr as uint, v)
+    }
+
+    fn emit_owned_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_managed_str(&self, v: &str) {
+        self.emit_borrowed_str(v)
+    }
+
+    fn emit_borrowed(&self, f: fn()) { f() }
+    fn emit_owned(&self, f: fn()) { f() }
+    fn emit_managed(&self, f: fn()) { f() }
 
     fn emit_enum(&self, name: &str, f: fn()) {
         self._emit_label(name);
@@ -397,25 +415,33 @@ impl Serializer: serialization2::Serializer {
     }
     fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() }
 
-    fn emit_vec(&self, len: uint, f: fn()) {
+    fn emit_borrowed_vec(&self, len: uint, f: fn()) {
         do self.wr_tag(EsVec as uint) {
             self._emit_tagged_uint(EsVecLen, len);
             f()
         }
     }
 
+    fn emit_owned_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
+    fn emit_managed_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+
     fn emit_vec_elt(&self, _idx: uint, f: fn()) {
         self.wr_tag(EsVecElt as uint, f)
     }
 
-    fn emit_box(&self, f: fn()) { f() }
-    fn emit_uniq(&self, f: fn()) { f() }
     fn emit_rec(&self, f: fn()) { f() }
-    fn emit_rec_field(&self, f_name: &str, _f_idx: uint, f: fn()) {
-        self._emit_label(f_name);
+    fn emit_struct(&self, _name: &str, f: fn()) { f() }
+    fn emit_field(&self, name: &str, _idx: uint, f: fn()) {
+        self._emit_label(name);
         f()
     }
-    fn emit_tup(&self, _sz: uint, f: fn()) { f() }
+
+    fn emit_tup(&self, _len: uint, f: fn()) { f() }
     fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() }
 }
 
@@ -525,9 +551,22 @@ impl Deserializer: serialization2::Deserializer {
     fn read_f32(&self) -> f32 { fail ~"read_f32()"; }
     fn read_float(&self) -> float { fail ~"read_float()"; }
 
-    fn read_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
+    fn read_char(&self) -> char { fail ~"read_char()"; }
+
+    fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
+    fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; }
 
     // Compound types:
+    fn read_owned<T>(&self, f: fn() -> T) -> T {
+        debug!("read_owned()");
+        f()
+    }
+
+    fn read_managed<T>(&self, f: fn() -> T) -> T {
+        debug!("read_managed()");
+        f()
+    }
+
     fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
         debug!("read_enum(%s)", name);
         self._check_label(name);
@@ -548,8 +587,17 @@ impl Deserializer: serialization2::Deserializer {
         f()
     }
 
-    fn read_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_vec()");
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_owned_vec()");
+        do self.push_doc(self.next_doc(EsVec)) {
+            let len = self._next_uint(EsVecLen);
+            debug!("  len=%u", len);
+            f(len)
+        }
+    }
+
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_managed_vec()");
         do self.push_doc(self.next_doc(EsVec)) {
             let len = self._next_uint(EsVecLen);
             debug!("  len=%u", len);
@@ -562,30 +610,24 @@ impl Deserializer: serialization2::Deserializer {
         self.push_doc(self.next_doc(EsVecElt), f)
     }
 
-    fn read_box<T>(&self, f: fn() -> T) -> T {
-        debug!("read_box()");
+    fn read_rec<T>(&self, f: fn() -> T) -> T {
+        debug!("read_rec()");
         f()
     }
 
-    fn read_uniq<T>(&self, f: fn() -> T) -> T {
-        debug!("read_uniq()");
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T {
+        debug!("read_struct(name=%s)", name);
         f()
     }
 
-    fn read_rec<T>(&self, f: fn() -> T) -> T {
-        debug!("read_rec()");
-        f()
-    }
-
-    fn read_rec_field<T>(&self, f_name: &str, f_idx: uint,
-                         f: fn() -> T) -> T {
-        debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
-        self._check_label(f_name);
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
+        debug!("read_field(name=%s, idx=%u)", name, idx);
+        self._check_label(name);
         f()
     }
 
-    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T {
-        debug!("read_tup(sz=%u)", sz);
+    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
+        debug!("read_tup(len=%u)", len);
         f()
     }
 
@@ -595,7 +637,6 @@ impl Deserializer: serialization2::Deserializer {
     }
 }
 
-
 // ___________________________________________________________________________
 // Testing
 
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 09fb5441375..d3713bdb29d 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -92,10 +92,15 @@ pub impl Serializer: serialization2::Serializer {
         self.wr.write_str(float::to_str(v, 6u));
     }
 
-    fn emit_str(&self, v: &str) {
-        let s = escape_str(v);
-        self.wr.write_str(s);
-    }
+    fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
+
+    fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) }
+    fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
+    fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
+
+    fn emit_borrowed(&self, f: fn()) { f() }
+    fn emit_owned(&self, f: fn()) { f() }
+    fn emit_managed(&self, f: fn()) { f() }
 
     fn emit_enum(&self, name: &str, f: fn()) {
         if name != "option" { fail ~"only supports option enum" }
@@ -112,32 +117,41 @@ pub impl Serializer: serialization2::Serializer {
         f()
     }
 
-    fn emit_vec(&self, _len: uint, f: fn()) {
+    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
         self.wr.write_char('[');
         f();
         self.wr.write_char(']');
     }
-
+    fn emit_owned_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+    fn emit_managed_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
     fn emit_vec_elt(&self, idx: uint, f: fn()) {
         if idx != 0 { self.wr.write_char(','); }
         f()
     }
 
-    fn emit_box(&self, f: fn()) { f() }
-    fn emit_uniq(&self, f: fn()) { f() }
     fn emit_rec(&self, f: fn()) {
         self.wr.write_char('{');
         f();
         self.wr.write_char('}');
     }
-    fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
+    fn emit_struct(&self, _name: &str, f: fn()) {
+        self.wr.write_char('{');
+        f();
+        self.wr.write_char('}');
+    }
+    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
         if idx != 0 { self.wr.write_char(','); }
         self.wr.write_str(escape_str(name));
         self.wr.write_char(':');
         f();
     }
-    fn emit_tup(&self, sz: uint, f: fn()) {
-        self.emit_vec(sz, f);
+
+    fn emit_tup(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f);
     }
     fn emit_tup_elt(&self, idx: uint, f: fn()) {
         self.emit_vec_elt(idx, f)
@@ -182,7 +196,15 @@ pub impl PrettySerializer: serialization2::Serializer {
         self.wr.write_str(float::to_str(v, 6u));
     }
 
-    fn emit_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
+    fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) }
+
+    fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); }
+    fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) }
+    fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) }
+
+    fn emit_borrowed(&self, f: fn()) { f() }
+    fn emit_owned(&self, f: fn()) { f() }
+    fn emit_managed(&self, f: fn()) { f() }
 
     fn emit_enum(&self, name: &str, f: fn()) {
         if name != "option" { fail ~"only supports option enum" }
@@ -199,14 +221,19 @@ pub impl PrettySerializer: serialization2::Serializer {
         f()
     }
 
-    fn emit_vec(&self, _len: uint, f: fn()) {
+    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
         self.wr.write_char('[');
         self.indent += 2;
         f();
         self.indent -= 2;
         self.wr.write_char(']');
     }
-
+    fn emit_owned_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
+    fn emit_managed_vec(&self, len: uint, f: fn()) {
+        self.emit_borrowed_vec(len, f)
+    }
     fn emit_vec_elt(&self, idx: uint, f: fn()) {
         if idx == 0 {
             self.wr.write_char('\n');
@@ -217,8 +244,6 @@ pub impl PrettySerializer: serialization2::Serializer {
         f()
     }
 
-    fn emit_box(&self, f: fn()) { f() }
-    fn emit_uniq(&self, f: fn()) { f() }
     fn emit_rec(&self, f: fn()) {
         self.wr.write_char('{');
         self.indent += 2;
@@ -226,7 +251,10 @@ pub impl PrettySerializer: serialization2::Serializer {
         self.indent -= 2;
         self.wr.write_char('}');
     }
-    fn emit_rec_field(&self, name: &str, idx: uint, f: fn()) {
+    fn emit_struct(&self, _name: &str, f: fn()) {
+        self.emit_rec(f)
+    }
+    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
         if idx == 0 {
             self.wr.write_char('\n');
         } else {
@@ -238,43 +266,39 @@ pub impl PrettySerializer: serialization2::Serializer {
         f();
     }
     fn emit_tup(&self, sz: uint, f: fn()) {
-        self.emit_vec(sz, f);
+        self.emit_borrowed_vec(sz, f);
     }
     fn emit_tup_elt(&self, idx: uint, f: fn()) {
         self.emit_vec_elt(idx, f)
     }
 }
 
-pub fn to_serializer<S: serialization2::Serializer>(ser: &S, json: &Json) {
-    match *json {
-        Number(f) => ser.emit_float(f),
-        String(ref s) => ser.emit_str(*s),
-        Boolean(b) => ser.emit_bool(b),
-        List(v) => {
-            do ser.emit_vec(v.len()) || {
-                for v.eachi |i, elt| {
-                    ser.emit_vec_elt(i, || to_serializer(ser, elt))
-                }
-            }
-        }
-        Object(ref o) => {
-            do ser.emit_rec || {
-                let mut idx = 0;
-                for o.each |key, value| {
-                    do ser.emit_rec_field(*key, idx) {
-                        to_serializer(ser, value);
+pub impl Json: serialization2::Serializable {
+    fn serialize<S: serialization2::Serializer>(&self, s: &S) {
+        match *self {
+            Number(v) => v.serialize(s),
+            String(ref v) => v.serialize(s),
+            Boolean(v) => v.serialize(s),
+            List(v) => v.serialize(s),
+            Object(ref v) => {
+                do s.emit_rec || {
+                    let mut idx = 0;
+                    for v.each |key, value| {
+                        do s.emit_field(*key, idx) {
+                            value.serialize(s);
+                        }
+                        idx += 1;
                     }
-                    idx += 1;
                 }
-            }
+            },
+            Null => s.emit_nil(),
         }
-        Null => ser.emit_nil(),
     }
 }
 
 /// Serializes a json value into a io::writer
 pub fn to_writer(wr: io::Writer, json: &Json) {
-    to_serializer(&Serializer(wr), json)
+    json.serialize(&Serializer(wr))
 }
 
 /// Serializes a json value into a string
@@ -284,7 +308,7 @@ pub fn to_str(json: &Json) -> ~str {
 
 /// Serializes a json value into a io::writer
 pub fn to_pretty_writer(wr: io::Writer, json: &Json) {
-    to_serializer(&PrettySerializer(wr), json)
+    json.serialize(&PrettySerializer(wr))
 }
 
 /// Serializes a json value into a string
@@ -736,14 +760,35 @@ pub impl Deserializer: serialization2::Deserializer {
         }
     }
 
-    fn read_str(&self) -> ~str {
-        debug!("read_str");
+    fn read_char(&self) -> char {
+        let v = str::chars(self.read_owned_str());
+        if v.len() != 1 { fail ~"string must have one character" }
+        v[0]
+    }
+
+    fn read_owned_str(&self) -> ~str {
+        debug!("read_owned_str");
         match *self.pop() {
             String(ref s) => copy *s,
             _ => fail ~"not a string"
         }
     }
 
+    fn read_managed_str(&self) -> @str {
+        // FIXME(#3604): There's no way to convert from a ~str to a @str.
+        fail ~"read_managed_str()";
+    }
+
+    fn read_owned<T>(&self, f: fn() -> T) -> T {
+        debug!("read_owned()");
+        f()
+    }
+
+    fn read_managed<T>(&self, f: fn() -> T) -> T {
+        debug!("read_managed()");
+        f()
+    }
+
     fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T {
         debug!("read_enum(%s)", name);
         if name != ~"option" { fail ~"only supports the option enum" }
@@ -765,8 +810,19 @@ pub impl Deserializer: serialization2::Deserializer {
         f()
     }
 
-    fn read_vec<T>(&self, f: fn(uint) -> T) -> T {
-        debug!("read_vec()");
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_owned_vec()");
+        let len = match *self.peek() {
+            List(list) => list.len(),
+            _ => fail ~"not a list",
+        };
+        let res = f(len);
+        self.pop();
+        res
+    }
+
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T {
+        debug!("read_owned_vec()");
         let len = match *self.peek() {
             List(ref list) => list.len(),
             _ => fail ~"not a list",
@@ -790,16 +846,6 @@ pub impl Deserializer: serialization2::Deserializer {
         }
     }
 
-    fn read_box<T>(&self, f: fn() -> T) -> T {
-        debug!("read_box()");
-        f()
-    }
-
-    fn read_uniq<T>(&self, f: fn() -> T) -> T {
-        debug!("read_uniq()");
-        f()
-    }
-
     fn read_rec<T>(&self, f: fn() -> T) -> T {
         debug!("read_rec()");
         let value = f();
@@ -807,17 +853,23 @@ pub impl Deserializer: serialization2::Deserializer {
         value
     }
 
-    fn read_rec_field<T>(&self, f_name: &str, f_idx: uint,
-                         f: fn() -> T) -> T {
-        debug!("read_rec_field(%s, idx=%u)", f_name, f_idx);
+    fn read_struct<T>(&self, _name: &str, f: fn() -> T) -> T {
+        debug!("read_struct()");
+        let value = f();
+        self.pop();
+        value
+    }
+
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T {
+        debug!("read_rec_field(%s, idx=%u)", name, idx);
         let top = self.peek();
         match *top {
             Object(ref obj) => {
                 // FIXME(#3148) This hint should not be necessary.
                 let obj: &self/~Object = obj;
 
-                match obj.find_ref(&(f_name.to_unique())) {
-                    None => fail fmt!("no such field: %s", f_name),
+                match obj.find_ref(&name.to_unique()) {
+                    None => fail fmt!("no such field: %s", name),
                     Some(json) => {
                         self.stack.push(json);
                         f()
@@ -834,8 +886,8 @@ pub impl Deserializer: serialization2::Deserializer {
         }
     }
 
-    fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T {
-        debug!("read_tup(sz=%u)", sz);
+    fn read_tup<T>(&self, len: uint, f: fn() -> T) -> T {
+        debug!("read_tup(len=%u)", len);
         let value = f();
         self.pop();
         value
diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs
index 68421a217ee..87af519eb12 100644
--- a/src/libstd/prettyprint2.rs
+++ b/src/libstd/prettyprint2.rs
@@ -12,7 +12,7 @@ pub fn Serializer(wr: io::Writer) -> Serializer {
     Serializer { wr: wr }
 }
 
-impl Serializer: serialization2::Serializer {
+pub impl Serializer: serialization2::Serializer {
     fn emit_nil(&self) {
         self.wr.write_str(~"()")
     }
@@ -73,10 +73,37 @@ impl Serializer: serialization2::Serializer {
         self.wr.write_str(fmt!("%?_f32", v));
     }
 
-    fn emit_str(&self, v: &str) {
+    fn emit_char(&self, v: char) {
         self.wr.write_str(fmt!("%?", v));
     }
 
+    fn emit_borrowed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("&%?", v));
+    }
+
+    fn emit_owned_str(&self, v: &str) {
+        self.wr.write_str(fmt!("~%?", v));
+    }
+
+    fn emit_managed_str(&self, v: &str) {
+        self.wr.write_str(fmt!("@%?", v));
+    }
+
+    fn emit_borrowed(&self, f: fn()) {
+        self.wr.write_str(~"&");
+        f();
+    }
+
+    fn emit_owned(&self, f: fn()) {
+        self.wr.write_str(~"~");
+        f();
+    }
+
+    fn emit_managed(&self, f: fn()) {
+        self.wr.write_str(~"@");
+        f();
+    }
+
     fn emit_enum(&self, _name: &str, f: fn()) {
         f();
     }
@@ -94,24 +121,26 @@ impl Serializer: serialization2::Serializer {
         f();
     }
 
-    fn emit_vec(&self, _len: uint, f: fn()) {
-        self.wr.write_str(~"[");
+    fn emit_borrowed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"&[");
         f();
         self.wr.write_str(~"]");
     }
 
-    fn emit_vec_elt(&self, idx: uint, f: fn()) {
-        if idx > 0u { self.wr.write_str(~", "); }
+    fn emit_owned_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"~[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_box(&self, f: fn()) {
-        self.wr.write_str(~"@");
+    fn emit_managed_vec(&self, _len: uint, f: fn()) {
+        self.wr.write_str(~"@[");
         f();
+        self.wr.write_str(~"]");
     }
 
-    fn emit_uniq(&self, f: fn()) {
-        self.wr.write_str(~"~");
+    fn emit_vec_elt(&self, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
         f();
     }
 
@@ -121,14 +150,20 @@ impl Serializer: serialization2::Serializer {
         self.wr.write_str(~"}");
     }
 
-    fn emit_rec_field(&self, f_name: &str, f_idx: uint, f: fn()) {
-        if f_idx > 0u { self.wr.write_str(~", "); }
-        self.wr.write_str(f_name);
+    fn emit_struct(&self, name: &str, f: fn()) {
+        self.wr.write_str(fmt!("%s {", name));
+        f();
+        self.wr.write_str(~"}");
+    }
+
+    fn emit_field(&self, name: &str, idx: uint, f: fn()) {
+        if idx > 0u { self.wr.write_str(~", "); }
+        self.wr.write_str(name);
         self.wr.write_str(~": ");
         f();
     }
 
-    fn emit_tup(&self, _sz: uint, f: fn()) {
+    fn emit_tup(&self, _len: uint, f: fn()) {
         self.wr.write_str(~"(");
         f();
         self.wr.write_str(~")");
diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs
index 9cceccf42c6..5173ef163a2 100644
--- a/src/libstd/serialization2.rs
+++ b/src/libstd/serialization2.rs
@@ -24,19 +24,30 @@ pub trait Serializer {
     fn emit_float(&self, v: float);
     fn emit_f64(&self, v: f64);
     fn emit_f32(&self, v: f32);
-    fn emit_str(&self, v: &str);
+    fn emit_char(&self, v: char);
+    fn emit_borrowed_str(&self, v: &str);
+    fn emit_owned_str(&self, v: &str);
+    fn emit_managed_str(&self, v: &str);
 
     // Compound types:
+    fn emit_borrowed(&self, f: fn());
+    fn emit_owned(&self, f: fn());
+    fn emit_managed(&self, f: fn());
+
     fn emit_enum(&self, name: &str, f: fn());
     fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn());
     fn emit_enum_variant_arg(&self, idx: uint, f: fn());
-    fn emit_vec(&self, len: uint, f: fn());
+
+    fn emit_borrowed_vec(&self, len: uint, f: fn());
+    fn emit_owned_vec(&self, len: uint, f: fn());
+    fn emit_managed_vec(&self, len: uint, f: fn());
     fn emit_vec_elt(&self, idx: uint, f: fn());
-    fn emit_box(&self, f: fn());
-    fn emit_uniq(&self, f: fn());
+
     fn emit_rec(&self, f: fn());
-    fn emit_rec_field(&self, f_name: &str, f_idx: uint, f: fn());
-    fn emit_tup(&self, sz: uint, f: fn());
+    fn emit_struct(&self, name: &str, f: fn());
+    fn emit_field(&self, f_name: &str, f_idx: uint, f: fn());
+
+    fn emit_tup(&self, len: uint, f: fn());
     fn emit_tup_elt(&self, idx: uint, f: fn());
 }
 
@@ -57,29 +68,43 @@ pub trait Deserializer {
     fn read_f64(&self) -> f64;
     fn read_f32(&self) -> f32;
     fn read_float(&self) -> float;
-    fn read_str(&self) -> ~str;
+    fn read_char(&self) -> char;
+    fn read_owned_str(&self) -> ~str;
+    fn read_managed_str(&self) -> @str;
 
     // Compound types:
     fn read_enum<T>(&self, name: &str, f: fn() -> T) -> T;
     fn read_enum_variant<T>(&self, f: fn(uint) -> T) -> T;
     fn read_enum_variant_arg<T>(&self, idx: uint, f: fn() -> T) -> T;
-    fn read_vec<T>(&self, f: fn(uint) -> T) -> T;
+
+    fn read_owned<T>(&self, f: fn() -> T) -> T;
+    fn read_managed<T>(&self, f: fn() -> T) -> T;
+
+    fn read_owned_vec<T>(&self, f: fn(uint) -> T) -> T;
+    fn read_managed_vec<T>(&self, f: fn(uint) -> T) -> T;
     fn read_vec_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
-    fn read_box<T>(&self, f: fn() -> T) -> T;
-    fn read_uniq<T>(&self, f: fn() -> T) -> T;
+
     fn read_rec<T>(&self, f: fn() -> T) -> T;
-    fn read_rec_field<T>(&self, f_name: &str, f_idx: uint, f: fn() -> T) -> T;
+    fn read_struct<T>(&self, name: &str, f: fn() -> T) -> T;
+    fn read_field<T>(&self, name: &str, idx: uint, f: fn() -> T) -> T;
+
     fn read_tup<T>(&self, sz: uint, f: fn() -> T) -> T;
     fn read_tup_elt<T>(&self, idx: uint, f: fn() -> T) -> T;
 }
 
 pub trait Serializable {
     fn serialize<S: Serializer>(&self, s: &S);
+}
+
+pub trait Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> self;
 }
 
 pub impl uint: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_uint(*self) }
+}
+
+pub impl uint: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> uint {
         d.read_uint()
     }
@@ -87,6 +112,9 @@ pub impl uint: Serializable {
 
 pub impl u8: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_u8(*self) }
+}
+
+pub impl u8: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> u8 {
         d.read_u8()
     }
@@ -94,6 +122,9 @@ pub impl u8: Serializable {
 
 pub impl u16: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_u16(*self) }
+}
+
+pub impl u16: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> u16 {
         d.read_u16()
     }
@@ -101,6 +132,9 @@ pub impl u16: Serializable {
 
 pub impl u32: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_u32(*self) }
+}
+
+pub impl u32: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> u32 {
         d.read_u32()
     }
@@ -108,6 +142,9 @@ pub impl u32: Serializable {
 
 pub impl u64: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_u64(*self) }
+}
+
+pub impl u64: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> u64 {
         d.read_u64()
     }
@@ -115,6 +152,9 @@ pub impl u64: Serializable {
 
 pub impl int: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_int(*self) }
+}
+
+pub impl int: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> int {
         d.read_int()
     }
@@ -122,6 +162,9 @@ pub impl int: Serializable {
 
 pub impl i8: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_i8(*self) }
+}
+
+pub impl i8: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> i8 {
         d.read_i8()
     }
@@ -129,6 +172,9 @@ pub impl i8: Serializable {
 
 pub impl i16: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_i16(*self) }
+}
+
+pub impl i16: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> i16 {
         d.read_i16()
     }
@@ -136,6 +182,9 @@ pub impl i16: Serializable {
 
 pub impl i32: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_i32(*self) }
+}
+
+pub impl i32: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> i32 {
         d.read_i32()
     }
@@ -143,20 +192,43 @@ pub impl i32: Serializable {
 
 pub impl i64: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_i64(*self) }
+}
+
+pub impl i64: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> i64 {
         d.read_i64()
     }
 }
 
+pub impl &str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_borrowed_str(*self) }
+}
+
 pub impl ~str: Serializable {
-    fn serialize<S: Serializer>(&self, s: &S) { s.emit_str(*self) }
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_owned_str(*self) }
+}
+
+pub impl ~str: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> ~str {
-        d.read_str()
+        d.read_owned_str()
+    }
+}
+
+pub impl @str: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) { s.emit_managed_str(*self) }
+}
+
+pub impl @str: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @str {
+        d.read_managed_str()
     }
 }
 
 pub impl float: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_float(*self) }
+}
+
+pub impl float: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> float {
         d.read_float()
     }
@@ -164,12 +236,18 @@ pub impl float: Serializable {
 
 pub impl f32: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_f32(*self) }
+}
+
+pub impl f32: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> f32 {
         d.read_f32() }
 }
 
 pub impl f64: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_f64(*self) }
+}
+
+pub impl f64: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> f64 {
         d.read_f64()
     }
@@ -177,6 +255,9 @@ pub impl f64: Serializable {
 
 pub impl bool: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_bool(*self) }
+}
+
+pub impl bool: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> bool {
         d.read_bool()
     }
@@ -184,42 +265,67 @@ pub impl bool: Serializable {
 
 pub impl (): Serializable {
     fn serialize<S: Serializer>(&self, s: &S) { s.emit_nil() }
+}
+
+pub impl (): Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> () {
         d.read_nil()
     }
 }
 
-pub impl<T: Serializable> @T: Serializable {
+pub impl<T: Serializable> &T: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_box(|| (*self).serialize(s))
-    }
-
-    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
-        d.read_box(|| @deserialize(d))
+        s.emit_borrowed(|| (**self).serialize(s))
     }
 }
 
 pub impl<T: Serializable> ~T: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) {
-        s.emit_uniq(|| (*self).serialize(s))
+        s.emit_owned(|| (**self).serialize(s))
     }
+}
 
+pub impl<T: Deserializable> ~T: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> ~T {
-        d.read_uniq(|| ~deserialize(d))
+        d.read_owned(|| ~deserialize(d))
+    }
+}
+
+pub impl<T: Serializable> @T: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        s.emit_managed(|| (**self).serialize(s))
+    }
+}
+
+pub impl<T: Deserializable> @T: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @T {
+        d.read_managed(|| @deserialize(d))
+    }
+}
+
+pub impl<T: Serializable> &[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_borrowed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
     }
 }
 
 pub impl<T: Serializable> ~[T]: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) {
-        do s.emit_vec(self.len()) {
+        do s.emit_owned_vec(self.len()) {
             for self.eachi |i, e| {
                 s.emit_vec_elt(i, || e.serialize(s))
             }
         }
     }
+}
 
+pub impl<T: Deserializable> ~[T]: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> ~[T] {
-        do d.read_vec |len| {
+        do d.read_owned_vec |len| {
             do vec::from_fn(len) |i| {
                 d.read_vec_elt(i, || deserialize(d))
             }
@@ -227,6 +333,26 @@ pub impl<T: Serializable> ~[T]: Serializable {
     }
 }
 
+pub impl<T: Serializable> @[T]: Serializable {
+    fn serialize<S: Serializer>(&self, s: &S) {
+        do s.emit_managed_vec(self.len()) {
+            for self.eachi |i, e| {
+                s.emit_vec_elt(i, || e.serialize(s))
+            }
+        }
+    }
+}
+
+pub impl<T: Deserializable> @[T]: Deserializable {
+    static fn deserialize<D: Deserializer>(&self, d: &D) -> @[T] {
+        do d.read_managed_vec |len| {
+            do at_vec::from_fn(len) |i| {
+                d.read_vec_elt(i, || deserialize(d))
+            }
+        }
+    }
+}
+
 pub impl<T: Serializable> Option<T>: Serializable {
     fn serialize<S: Serializer>(&self, s: &S) {
         do s.emit_enum(~"option") {
@@ -240,7 +366,9 @@ pub impl<T: Serializable> Option<T>: Serializable {
             }
         }
     }
+}
 
+pub impl<T: Deserializable> Option<T>: Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> Option<T> {
         do d.read_enum(~"option") {
             do d.read_enum_variant |i| {
@@ -268,7 +396,12 @@ pub impl<
             }
         }
     }
+}
 
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable
+> (T0, T1): Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1) {
         do d.read_tup(2) {
             (
@@ -295,7 +428,13 @@ pub impl<
             }
         }
     }
+}
 
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable
+> (T0, T1, T2): Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2) {
         do d.read_tup(3) {
             (
@@ -325,7 +464,14 @@ pub impl<
             }
         }
     }
+}
 
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable
+> (T0, T1, T2, T3): Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D) -> (T0, T1, T2, T3) {
         do d.read_tup(4) {
             (
@@ -358,7 +504,15 @@ pub impl<
             }
         }
     }
+}
 
+pub impl<
+    T0: Deserializable,
+    T1: Deserializable,
+    T2: Deserializable,
+    T3: Deserializable,
+    T4: Deserializable
+> (T0, T1, T2, T3, T4): Deserializable {
     static fn deserialize<D: Deserializer>(&self, d: &D)
       -> (T0, T1, T2, T3, T4) {
         do d.read_tup(5) {
@@ -379,12 +533,12 @@ pub impl<
 // In some cases, these should eventually be coded as traits.
 
 pub trait SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T));
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T));
 }
 
 pub impl<S: Serializer> S: SerializerHelpers {
-    fn emit_from_vec<T>(&self, v: ~[T], f: fn(v: &T)) {
-        do self.emit_vec(v.len()) {
+    fn emit_from_vec<T>(&self, v: &[T], f: fn(&T)) {
+        do self.emit_owned_vec(v.len()) {
             for v.eachi |i, e| {
                 do self.emit_vec_elt(i) {
                     f(e)
@@ -400,7 +554,7 @@ pub trait DeserializerHelpers {
 
 pub impl<D: Deserializer> D: DeserializerHelpers {
     fn read_to_vec<T>(&self, f: fn() -> T) -> ~[T] {
-        do self.read_vec |len| {
+        do self.read_owned_vec |len| {
             do vec::from_fn(len) |i| {
                 self.read_vec_elt(i, || f())
             }