Leave unused keys in TOML while decoding
This commit is contained in:
parent
7ba80c5ac4
commit
c28df7cb52
|
@ -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)
|
||||
})
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue