about summary refs log tree commit diff
diff options
context:
space:
mode:
authormitchmindtree <mitchell.nordine@gmail.com>2014-07-04 22:24:50 +1000
committermitchmindtree <mitchell.nordine@gmail.com>2014-07-07 13:02:09 +1000
commit0e84d6fc1ae1267eaf38b9c518a6d8f68ff6305c (patch)
treedf1a8f1e2ab0682881923c430c991889f32a15dc
parent36d7d746c8366d78b332cffdff85318e709b38ca (diff)
downloadrust-0e84d6fc1ae1267eaf38b9c518a6d8f68ff6305c.tar.gz
rust-0e84d6fc1ae1267eaf38b9c518a6d8f68ff6305c.zip
Implemented Decodable/Encodable for Cell and RefCell. Fixes #15395
Updated PR with fixme and test

Updated PR with fixme and test
-rw-r--r--src/libserialize/serialize.rs30
-rw-r--r--src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs55
2 files changed, 85 insertions, 0 deletions
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 0ed555e392f..03d9445b9b9 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -17,6 +17,7 @@ Core encoding and decoding interfaces.
 use std::path;
 use std::rc::Rc;
 use std::gc::{Gc, GC};
+use std::cell::{Cell, RefCell};
 
 pub trait Encoder<E> {
     // Primitive types:
@@ -536,6 +537,35 @@ impl<E, D: Decoder<E>> Decodable<D, E> for path::windows::Path {
     }
 }
 
+impl<E, S: Encoder<E>, T: Encodable<S, E> + Copy> Encodable<S, E> for Cell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.get().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E> + Copy> Decodable<D, E> for Cell<T> {
+    fn decode(d: &mut D) -> Result<Cell<T>, E> {
+        Ok(Cell::new(try!(Decodable::decode(d))))
+    }
+}
+
+// FIXME: #15036
+// Should use `try_borrow`, returning a
+// `encoder.error("attempting to Encode borrowed RefCell")`
+// from `encode` when `try_borrow` returns `None`.
+
+impl<E, S: Encoder<E>, T: Encodable<S, E>> Encodable<S, E> for RefCell<T> {
+    fn encode(&self, s: &mut S) -> Result<(), E> {
+        self.borrow().encode(s)
+    }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
+    fn decode(d: &mut D) -> Result<RefCell<T>, E> {
+        Ok(RefCell::new(try!(Decodable::decode(d))))
+    }
+}
+
 // ___________________________________________________________________________
 // Helper routines
 //
diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
new file mode 100644
index 00000000000..a7738bb803c
--- /dev/null
+++ b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
@@ -0,0 +1,55 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This briefuly tests the capability of `Cell` and `RefCell` to implement the
+// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
+
+extern crate serialize;
+
+use std::cell::{Cell, RefCell};
+use std::io::MemWriter;
+use serialize::{Encodable, Decodable};
+use serialize::ebml;
+use serialize::ebml::writer::Encoder;
+use serialize::ebml::reader::Decoder;
+
+#[deriving(Encodable, Decodable)]
+struct A {
+    baz: int
+}
+
+#[deriving(Encodable, Decodable)]
+struct B {
+    foo: Cell<bool>,
+    bar: RefCell<A>,
+}
+
+fn main() {
+    let obj = B {
+        foo: Cell::new(true),
+        bar: RefCell::new( A { baz: 2 } )
+    };
+    let mut w = MemWriter::new();
+    {
+        let mut e = Encoder::new(&mut w);
+        match obj.encode(&mut e) {
+            Ok(()) => (),
+            Err(e) => fail!("Failed to encode: {}", e)
+        };
+    }
+    let doc = ebml::Doc::new(w.get_ref());
+    let mut dec = Decoder::new(doc);
+    let obj2: B = match Decodable::decode(&mut dec) {
+        Ok(v) => v,
+        Err(e) => fail!("Failed to decode: {}", e)
+    };
+    assert!(obj.foo.get() == obj2.foo.get());
+    assert!(obj.bar.borrow().baz == obj2.bar.borrow().baz);
+}