From 4d6dcefcbb8688b69dd80bc7382a2f593c3b08d8 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Tue, 26 Mar 2013 18:46:48 -0700 Subject: 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. --- src/libstd/ebml.rs | 30 ++++++++++++++++++++++++++++++ src/libstd/json.rs | 27 +++++++++++++++++++++++++-- src/libstd/serialize.rs | 8 ++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) (limited to 'src/libstd') 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(&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(&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(&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(&self, f: &fn() -> T) -> Option { debug!("read_option()"); do self.read_enum("Option") || { @@ -412,6 +426,22 @@ pub mod reader { } } } + + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn read_option(&self, f: &fn() -> T) -> Option { + 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(&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(&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(&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(&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(&self, name: &str, f: &fn() -> T) -> T; + + #[cfg(stage0)] fn read_enum_variant(&self, f: &fn(uint) -> T) -> T; + + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn read_enum_variant(&self, names: &[&str], f: &fn(uint) -> T) -> T; + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T; fn read_owned(&self, f: &fn() -> T) -> T; -- cgit 1.4.1-3-g733a5