aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-06-26 22:52:31 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-26 22:52:31 -0700
commitc28df7cb52f537975866b43ca28ea5d1a38f7d17 (patch)
tree695936c1c4382c2df7772f63dfc496655d939d8a /src
parent7ba80c5ac4a3f6bc3801bb4ac86fd65a569a07ba (diff)
downloadmilf-rs-c28df7cb52f537975866b43ca28ea5d1a38f7d17.tar.gz
milf-rs-c28df7cb52f537975866b43ca28ea5d1a38f7d17.zip
Leave unused keys in TOML while decoding
Diffstat (limited to 'src')
-rw-r--r--src/serialization.rs84
1 files changed, 71 insertions, 13 deletions
diff --git a/src/serialization.rs b/src/serialization.rs
index 7011eb6..e5bce42 100644
--- a/src/serialization.rs
+++ b/src/serialization.rs
@@ -48,7 +48,7 @@ pub struct Encoder {
/// `Decodable` types to be generated by this decoder. The input is any
/// arbitrary TOML value.
pub struct Decoder {
- toml: Option<Value>,
+ pub toml: Option<Value>,
cur_field: Option<String>,
}
@@ -403,10 +403,12 @@ impl Decoder {
impl serialize::Decoder<DecodeError> for Decoder {
fn read_nil(&mut self) -> Result<(), DecodeError> {
match self.toml {
- Some(String(ref s)) if s.len() == 0 => Ok(()),
- Some(String(..)) => Err(self.err(NilTooLong)),
- ref found => Err(self.mismatch("string", found)),
+ Some(String(ref s)) if s.len() == 0 => {}
+ Some(String(..)) => return Err(self.err(NilTooLong)),
+ ref found => return Err(self.mismatch("string", found)),
}
+ self.toml.take();
+ Ok(())
}
fn read_uint(&mut self) -> Result<uint, DecodeError> {
self.read_i64().map(|i| i as uint)
@@ -428,7 +430,7 @@ impl serialize::Decoder<DecodeError> for Decoder {
}
fn read_i64(&mut self) -> Result<i64, DecodeError> {
match self.toml {
- Some(Integer(i)) => Ok(i),
+ Some(Integer(i)) => { self.toml.take(); Ok(i) }
ref found => Err(self.mismatch("integer", found)),
}
}
@@ -443,7 +445,7 @@ impl serialize::Decoder<DecodeError> for Decoder {
}
fn read_bool(&mut self) -> Result<bool, DecodeError> {
match self.toml {
- Some(Boolean(b)) => Ok(b),
+ Some(Boolean(b)) => { self.toml.take(); Ok(b) }
ref found => Err(self.mismatch("bool", found)),
}
}
@@ -457,16 +459,22 @@ impl serialize::Decoder<DecodeError> for Decoder {
self.read_f64().map(|f| f as f32)
}
fn read_char(&mut self) -> Result<char, DecodeError> {
- match self.toml {
+ let ch = match self.toml {
Some(String(ref s)) if s.as_slice().char_len() == 1 =>
- Ok(s.as_slice().char_at(0)),
- ref found => Err(self.mismatch("string", found)),
- }
+ s.as_slice().char_at(0),
+ ref found => return Err(self.mismatch("string", found)),
+ };
+ self.toml.take();
+ Ok(ch)
}
fn read_str(&mut self) -> Result<String, DecodeError> {
match self.toml.take() {
Some(String(s)) => Ok(s),
- ref found => Err(self.mismatch("string", found)),
+ found => {
+ let err = Err(self.mismatch("string", &found));
+ self.toml = found;
+ err
+ }
}
}
@@ -535,11 +543,21 @@ impl serialize::Decoder<DecodeError> for Decoder {
_f_idx: uint,
f: |&mut Decoder| -> Result<T, DecodeError>)
-> Result<T, DecodeError> {
+ let field = f_name.to_string();
let toml = match self.toml {
- Some(Table(ref mut table)) => table.pop(&f_name.to_string()),
+ Some(Table(ref mut table)) => table.pop(&field),
ref found => return Err(self.mismatch("table", found)),
};
- f(&mut self.sub_decoder(toml, f_name))
+ let mut d = self.sub_decoder(toml, f_name);
+ let ret = try!(f(&mut d));
+ match d.toml {
+ Some(value) => match self.toml {
+ Some(Table(ref mut table)) => { table.insert(field, value); }
+ _ => {}
+ },
+ None => {}
+ }
+ Ok(ret)
}
fn read_tuple<T>(&mut self,
@@ -957,4 +975,44 @@ mod tests {
);
assert_eq!(v, decode!(Table(encode!(v))));
}
+
+ #[test]
+ fn unused_fields() {
+ #[deriving(Encodable, Decodable, PartialEq, Show)]
+ struct Foo { a: int }
+
+ let v = Foo { a: 2 };
+ let mut d = Decoder::new(Table(map! {
+ a: Integer(2),
+ b: Integer(5)
+ }));
+ assert_eq!(v, Decodable::decode(&mut d).unwrap());
+
+ assert_eq!(d.toml, Some(Table(map! {
+ b: Integer(5)
+ })));
+ }
+
+ #[test]
+ fn unused_fields2() {
+ #[deriving(Encodable, Decodable, PartialEq, Show)]
+ struct Foo { a: Bar }
+ #[deriving(Encodable, Decodable, PartialEq, Show)]
+ struct Bar { a: int }
+
+ let v = Foo { a: Bar { a: 2 } };
+ let mut d = Decoder::new(Table(map! {
+ a: Table(map! {
+ a: Integer(2),
+ b: Integer(5)
+ })
+ }));
+ assert_eq!(v, Decodable::decode(&mut d).unwrap());
+
+ assert_eq!(d.toml, Some(Table(map! {
+ a: Table(map! {
+ b: Integer(5)
+ })
+ })));
+ }
}