about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-03-26 18:46:48 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-03-27 07:04:13 -0700
commit4d6dcefcbb8688b69dd80bc7382a2f593c3b08d8 (patch)
tree0c688bb5af8a87ec2566e0d88da9b031e539e625 /src/libstd
parent478e4498b76178dc0031f88f0d5ee31c5f804d0b (diff)
downloadrust-4d6dcefcbb8688b69dd80bc7382a2f593c3b08d8.tar.gz
rust-4d6dcefcbb8688b69dd80bc7382a2f593c3b08d8.zip
std: Decode::read_enum_variant should pass in the variant names
Because the json::Decoder uses the string variant name, we need a
way to correlate the string to the enum index. This passes in a
static &[&str] to read_enum_variant, which allows the json::Decoder
to know which branch it's trying to process.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ebml.rs30
-rw-r--r--src/libstd/json.rs27
-rw-r--r--src/libstd/serialize.rs8
3 files changed, 63 insertions, 2 deletions
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 90389602bc4..60a00bee0ac 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -337,6 +337,7 @@ pub mod reader {
             self.push_doc(self.next_doc(EsEnum), f)
         }
 
+        #[cfg(stage0)]
         fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
             debug!("read_enum_variant()");
             let idx = self._next_uint(EsEnumVid);
@@ -346,6 +347,18 @@ pub mod reader {
             }
         }
 
+        #[cfg(stage1)]
+        #[cfg(stage2)]
+        #[cfg(stage3)]
+        fn read_enum_variant<T>(&self, _names: &[&str], f: &fn(uint) -> T) -> T {
+            debug!("read_enum_variant()");
+            let idx = self._next_uint(EsEnumVid);
+            debug!("  idx=%u", idx);
+            do self.push_doc(self.next_doc(EsEnumBody)) {
+                f(idx)
+            }
+        }
+
         fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
             debug!("read_enum_variant_arg(idx=%u)", idx);
             f()
@@ -400,6 +413,7 @@ pub mod reader {
             f()
         }
 
+        #[cfg(stage0)]
         fn read_option<T>(&self, f: &fn() -> T) -> Option<T> {
             debug!("read_option()");
             do self.read_enum("Option") || {
@@ -412,6 +426,22 @@ pub mod reader {
                 }
             }
         }
+
+        #[cfg(stage1)]
+        #[cfg(stage2)]
+        #[cfg(stage3)]
+        fn read_option<T>(&self, f: &fn() -> T) -> Option<T> {
+            debug!("read_option()");
+            do self.read_enum("Option") || {
+                do self.read_enum_variant(["None", "Some"]) |idx| {
+                    match idx {
+                        0 => None,
+                        1 => Some(f()),
+                        _ => fail!(),
+                    }
+                }
+            }
+        }
     }
 }
 
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index bb1102be9f7..dc9f629d7e2 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -855,6 +855,7 @@ impl<'self> serialize::Decoder for Decoder<'self> {
         f()
     }
 
+    #[cfg(stage0)]
     fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T {
         debug!("read_enum_variant()");
         let idx = match *self.peek() {
@@ -864,10 +865,32 @@ impl<'self> serialize::Decoder for Decoder<'self> {
         f(idx)
     }
 
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T {
+        debug!("read_enum_variant(names=%?)", names);
+        let name = match *self.peek() {
+            String(ref s) => s,
+            List([String(ref s), .. _]) => s,
+            json => fail!(fmt!("invalid variant: %?", json)),
+        };
+        let idx = match vec::position(names, |n| str::eq_slice(*n, *name)) {
+            Some(idx) => idx,
+            None => fail!(fmt!("Unknown variant name: %?", name)),
+        };
+        f(idx)
+    }
+
     fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T {
         debug!("read_enum_variant_arg(idx=%u)", idx);
-        if idx != 0 { fail!(~"unknown index") }
-        f()
+        match *self.peek() {
+            List(ref list) => {
+                self.stack.push(&list[idx + 1]);
+                f()
+            }
+            ref json => fail!(fmt!("not a list: %?", json)),
+        }
     }
 
     fn read_owned_vec<T>(&self, f: &fn(uint) -> T) -> T {
diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs
index 69977c6e4fe..02f4a934874 100644
--- a/src/libstd/serialize.rs
+++ b/src/libstd/serialize.rs
@@ -92,7 +92,15 @@ pub trait Decoder {
 
     // Compound types:
     fn read_enum<T>(&self, name: &str, f: &fn() -> T) -> T;
+
+    #[cfg(stage0)]
     fn read_enum_variant<T>(&self, f: &fn(uint) -> T) -> T;
+
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn read_enum_variant<T>(&self, names: &[&str], f: &fn(uint) -> T) -> T;
+
     fn read_enum_variant_arg<T>(&self, idx: uint, f: &fn() -> T) -> T;
 
     fn read_owned<T>(&self, f: &fn() -> T) -> T;