aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-03-20 10:53:21 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-03-20 10:53:36 -0700
commit2c5aa077225bb0acea2bf81912a8774e8707a518 (patch)
treef9a77403d6d5943a796218abec5057591b93b739
parentb852af0a6000efa6cf444a48b27eda7cd67b6761 (diff)
downloadmilf-rs-2c5aa077225bb0acea2bf81912a8774e8707a518.tar.gz
milf-rs-2c5aa077225bb0acea2bf81912a8774e8707a518.zip
Implement Encodable for Value
We can't generically decode into one, but we can generically encode one! Closes #58
-rw-r--r--src/lib.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 4b87b69..85c340a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -65,11 +65,11 @@ mod serialization;
#[derive(PartialEq, Clone, Debug)]
#[allow(missing_docs)]
pub enum Value {
- String(string::String),
+ String(String),
Integer(i64),
Float(f64),
Boolean(bool),
- Datetime(string::String),
+ Datetime(String),
Array(Array),
Table(Table),
}
@@ -204,6 +204,37 @@ impl Value {
}
}
+impl rustc_serialize::Encodable for Value {
+ fn encode<E>(&self, e: &mut E) -> Result<(), E::Error>
+ where E: rustc_serialize::Encoder
+ {
+ match *self {
+ Value::String(ref s) => e.emit_str(s),
+ Value::Integer(i) => e.emit_i64(i),
+ Value::Float(f) => e.emit_f64(f),
+ Value::Boolean(b) => e.emit_bool(b),
+ Value::Datetime(ref s) => e.emit_str(s),
+ Value::Array(ref a) => {
+ e.emit_seq(a.len(), |e| {
+ for item in a {
+ try!(item.encode(e));
+ }
+ Ok(())
+ })
+ }
+ Value::Table(ref t) => {
+ e.emit_map(t.len(), |e| {
+ for (i, (key, value)) in t.iter().enumerate() {
+ try!(e.emit_map_elt_key(i, |e| e.emit_str(key)));
+ try!(e.emit_map_elt_val(i, |e| value.encode(e)));
+ }
+ Ok(())
+ })
+ }
+ }
+ }
+}
+
impl FromStr for Value {
type Err = Vec<ParserError>;
fn from_str(s: &str) -> Result<Value, Vec<ParserError>> {
@@ -262,4 +293,22 @@ mod tests {
let foo = value.lookup("values.str.foo");
assert!(foo.is_none());
}
+
+ #[test]
+ fn round_trip() {
+ let toml = r#"
+ [test]
+ foo = "bar"
+
+ [[values]]
+ foo = "baz"
+
+ [[values]]
+ foo = "qux"
+ "#;
+
+ let value: Value = toml.parse().unwrap();
+ let val2 = ::encode_str(&value).parse().unwrap();
+ assert_eq!(value, val2);
+ }
}