Leave unused keys in TOML while decoding

This commit is contained in:
Alex Crichton 2014-06-26 22:52:31 -07:00
parent 7ba80c5ac4
commit c28df7cb52

View file

@ -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)
})
})));
}
}