diff options
| author | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-03-26 18:46:48 -0700 |
|---|---|---|
| committer | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-03-27 07:04:13 -0700 |
| commit | 4d6dcefcbb8688b69dd80bc7382a2f593c3b08d8 (patch) | |
| tree | 0c688bb5af8a87ec2566e0d88da9b031e539e625 /src/libstd | |
| parent | 478e4498b76178dc0031f88f0d5ee31c5f804d0b (diff) | |
| download | rust-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.rs | 30 | ||||
| -rw-r--r-- | src/libstd/json.rs | 27 | ||||
| -rw-r--r-- | src/libstd/serialize.rs | 8 |
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; |
