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
|
/// `Decodable` types to be generated by this decoder. The input is any
|
||||||
/// arbitrary TOML value.
|
/// arbitrary TOML value.
|
||||||
pub struct Decoder {
|
pub struct Decoder {
|
||||||
toml: Option<Value>,
|
pub toml: Option<Value>,
|
||||||
cur_field: Option<String>,
|
cur_field: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,10 +403,12 @@ impl Decoder {
|
||||||
impl serialize::Decoder<DecodeError> for Decoder {
|
impl serialize::Decoder<DecodeError> for Decoder {
|
||||||
fn read_nil(&mut self) -> Result<(), DecodeError> {
|
fn read_nil(&mut self) -> Result<(), DecodeError> {
|
||||||
match self.toml {
|
match self.toml {
|
||||||
Some(String(ref s)) if s.len() == 0 => Ok(()),
|
Some(String(ref s)) if s.len() == 0 => {}
|
||||||
Some(String(..)) => Err(self.err(NilTooLong)),
|
Some(String(..)) => return Err(self.err(NilTooLong)),
|
||||||
ref found => Err(self.mismatch("string", found)),
|
ref found => return Err(self.mismatch("string", found)),
|
||||||
}
|
}
|
||||||
|
self.toml.take();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
fn read_uint(&mut self) -> Result<uint, DecodeError> {
|
fn read_uint(&mut self) -> Result<uint, DecodeError> {
|
||||||
self.read_i64().map(|i| i as uint)
|
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> {
|
fn read_i64(&mut self) -> Result<i64, DecodeError> {
|
||||||
match self.toml {
|
match self.toml {
|
||||||
Some(Integer(i)) => Ok(i),
|
Some(Integer(i)) => { self.toml.take(); Ok(i) }
|
||||||
ref found => Err(self.mismatch("integer", found)),
|
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> {
|
fn read_bool(&mut self) -> Result<bool, DecodeError> {
|
||||||
match self.toml {
|
match self.toml {
|
||||||
Some(Boolean(b)) => Ok(b),
|
Some(Boolean(b)) => { self.toml.take(); Ok(b) }
|
||||||
ref found => Err(self.mismatch("bool", found)),
|
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)
|
self.read_f64().map(|f| f as f32)
|
||||||
}
|
}
|
||||||
fn read_char(&mut self) -> Result<char, DecodeError> {
|
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 =>
|
Some(String(ref s)) if s.as_slice().char_len() == 1 =>
|
||||||
Ok(s.as_slice().char_at(0)),
|
s.as_slice().char_at(0),
|
||||||
ref found => Err(self.mismatch("string", found)),
|
ref found => return Err(self.mismatch("string", found)),
|
||||||
}
|
};
|
||||||
|
self.toml.take();
|
||||||
|
Ok(ch)
|
||||||
}
|
}
|
||||||
fn read_str(&mut self) -> Result<String, DecodeError> {
|
fn read_str(&mut self) -> Result<String, DecodeError> {
|
||||||
match self.toml.take() {
|
match self.toml.take() {
|
||||||
Some(String(s)) => Ok(s),
|
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_idx: uint,
|
||||||
f: |&mut Decoder| -> Result<T, DecodeError>)
|
f: |&mut Decoder| -> Result<T, DecodeError>)
|
||||||
-> Result<T, DecodeError> {
|
-> Result<T, DecodeError> {
|
||||||
|
let field = f_name.to_string();
|
||||||
let toml = match self.toml {
|
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)),
|
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,
|
fn read_tuple<T>(&mut self,
|
||||||
|
@ -957,4 +975,44 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(v, decode!(Table(encode!(v))));
|
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