diff options
| author | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-03-26 15:26:05 -0700 |
|---|---|---|
| committer | Erick Tryzelaar <erick.tryzelaar@gmail.com> | 2013-03-27 07:04:12 -0700 |
| commit | 478e4498b76178dc0031f88f0d5ee31c5f804d0b (patch) | |
| tree | e21be7cccf5b3fa4c2d05f2719e6679936096ab0 /src/libstd | |
| parent | 4d995e66a274511d70eb02abdb80da43ccf70aee (diff) | |
std: add option type directly to serialize::{En,De}code
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ebml.rs | 26 | ||||
| -rw-r--r-- | src/libstd/json.rs | 38 | ||||
| -rw-r--r-- | src/libstd/prettyprint.rs | 14 | ||||
| -rw-r--r-- | src/libstd/serialize.rs | 29 |
4 files changed, 68 insertions, 39 deletions
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 92898af2993..90389602bc4 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -399,8 +399,20 @@ pub mod reader { debug!("read_tup_elt(idx=%u)", idx); f() } - } + fn read_option<T>(&self, f: &fn() -> T) -> Option<T> { + debug!("read_option()"); + do self.read_enum("Option") || { + do self.read_enum_variant |idx| { + match idx { + 0 => None, + 1 => Some(f()), + _ => fail!(), + } + } + } + } + } } pub mod writer { @@ -666,9 +678,19 @@ pub mod writer { fn emit_tup(&self, _len: uint, f: &fn()) { f() } fn emit_tup_elt(&self, _idx: uint, f: &fn()) { f() } - } + fn emit_option(&self, f: &fn()) { + self.emit_enum("Option", f); + } + fn emit_option_none(&self) { + self.emit_enum_variant("None", 0, 0, || ()) + } + fn emit_option_some(&self, f: &fn()) { + self.emit_enum_variant("Some", 1, 1, f) + } + } } + // ___________________________________________________________________________ // Testing diff --git a/src/libstd/json.rs b/src/libstd/json.rs index d69917c9aff..bb1102be9f7 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -120,24 +120,11 @@ impl serialize::Encoder for Encoder { } fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) { - // encoding of enums is special-cased for Option. Specifically: - // Some(34) => 34 - // None => null - - // other enums are encoded as strings or vectors: + // enums are encoded as strings or vectors: // Bunny => "Bunny" // Kangaroo(34,"William") => ["Kangaroo",[34,"William"]] - // FIXME #4872: this would be more precise and less frightening - // with fully-qualified option names. To get that information, - // we'd have to change the expansion of auto-encode to pass - // those along. - - if name == ~"Some" { - f(); - } else if name == ~"None" { - self.wr.write_str(~"null"); - } else if cnt == 0 { + if cnt == 0 { self.wr.write_str(escape_str(name)); } else { self.wr.write_char('['); @@ -193,6 +180,10 @@ impl serialize::Encoder for Encoder { fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } + + fn emit_option(&self, f: &fn()) { f(); } + fn emit_option_none(&self) { self.emit_nil(); } + fn emit_option_some(&self, f: &fn()) { f(); } } pub struct PrettyEncoder { @@ -245,11 +236,7 @@ impl serialize::Encoder for PrettyEncoder { fn emit_enum(&self, _name: &str, f: &fn()) { f() } fn emit_enum_variant(&self, name: &str, _id: uint, cnt: uint, f: &fn()) { - if name == ~"Some" { - f(); - } else if name == ~"None" { - self.emit_nil(); - } else if cnt == 0 { + if cnt == 0 { self.wr.write_str(escape_str(name)); } else { self.wr.write_char('['); @@ -335,6 +322,10 @@ impl serialize::Encoder for PrettyEncoder { fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } + + fn emit_option(&self, f: &fn()) { f(); } + fn emit_option_none(&self) { self.emit_nil(); } + fn emit_option_some(&self, f: &fn()) { f(); } } impl<S:serialize::Encoder> serialize::Encodable<S> for Json { @@ -966,6 +957,13 @@ impl<'self> serialize::Decoder for Decoder<'self> { _ => fail!(~"not a list") } } + + fn read_option<T>(&self, f: &fn() -> T) -> Option<T> { + match *self.peek() { + Null => { self.pop(); None } + _ => Some(f()), + } + } } impl Eq for Json { diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index f823d73cf0b..ed4f3e957c0 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -182,4 +182,18 @@ impl serialize::Encoder for Serializer { if idx > 0u { self.wr.write_str(~", "); } f(); } + + fn emit_option(&self, f: &fn()) { + f(); + } + + fn emit_option_none(&self) { + self.wr.write_str("None"); + } + + fn emit_option_some(&self, f: &fn()) { + self.wr.write_str("Some("); + f(); + self.wr.write_char(')'); + } } diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 8e4bbc87b08..69977c6e4fe 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -62,6 +62,11 @@ pub trait Encoder { fn emit_tup(&self, len: uint, f: &fn()); fn emit_tup_elt(&self, idx: uint, f: &fn()); + + // Specialized types: + fn emit_option(&self, f: &fn()); + fn emit_option_none(&self); + fn emit_option_some(&self, f: &fn()); } pub trait Decoder { @@ -103,6 +108,9 @@ pub trait Decoder { fn read_tup<T>(&self, sz: uint, f: &fn() -> T) -> T; fn read_tup_elt<T>(&self, idx: uint, f: &fn() -> T) -> T; + + // Specialized types: + fn read_option<T>(&self, f: &fn() -> T) -> Option<T>; } pub trait Encodable<S:Encoder> { @@ -368,14 +376,10 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for @[T] { impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> { fn encode(&self, s: &S) { - do s.emit_enum(~"Option") { + do s.emit_option { match *self { - None => do s.emit_enum_variant(~"None", 0u, 0u) { - }, - - Some(ref v) => do s.emit_enum_variant(~"Some", 1u, 1u) { - s.emit_enum_variant_arg(0u, || v.encode(s)) - } + None => s.emit_option_none(), + Some(ref v) => s.emit_option_some(|| v.encode(s)), } } } @@ -383,16 +387,7 @@ 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: &D) -> Option<T> { - do d.read_enum(~"Option") { - do d.read_enum_variant |i| { - match i { - 0 => None, - 1 => Some(d.read_enum_variant_arg( - 0u, || Decodable::decode(d))), - _ => fail!(fmt!("Bad variant for option: %u", i)) - } - } - } + d.read_option(|| Decodable::decode(d)) } } |
