Rewrite the MapVisitor to add errors for a specific field

This commit is contained in:
Erick Tryzelaar 2015-08-13 08:24:59 -07:00
parent 8c33064c2c
commit 85cd6f3e6e

View file

@ -346,12 +346,20 @@ impl de::Error for DecodeError {
} }
} }
struct MapVisitor<'a, I> {
iter: I,
de: &'a mut Decoder,
key: Option<String>,
value: Option<Value>,
}
impl<'a, I> MapVisitor<'a, I> { impl<'a, I> MapVisitor<'a, I> {
fn put_value_back(&mut self, v: Value) { fn put_value_back(&mut self, v: Value) {
*self.toml = self.toml.take().or_else(|| { self.de.toml = self.de.toml.take().or_else(|| {
Some(Value::Table(BTreeMap::new())) Some(Value::Table(BTreeMap::new()))
}); });
match self.toml.as_mut().unwrap() {
match self.de.toml.as_mut().unwrap() {
&mut Value::Table(ref mut t) => { &mut Value::Table(ref mut t) => {
t.insert(self.key.take().unwrap(), v); t.insert(self.key.take().unwrap(), v);
}, },
@ -369,8 +377,9 @@ impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
where K: de::Deserialize where K: de::Deserialize
{ {
while let Some((k, v)) = self.iter.next() { while let Some((k, v)) = self.iter.next() {
self.key = Some(k.clone()); let mut dec = self.de.sub_decoder(Some(Value::String(k.clone())), &k);
let mut dec = Decoder::new(Value::String(k)); self.key = Some(k);
match de::Deserialize::deserialize(&mut dec) { match de::Deserialize::deserialize(&mut dec) {
Ok(val) => { Ok(val) => {
self.value = Some(v); self.value = Some(v);
@ -382,6 +391,7 @@ impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => { Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => {
self.put_value_back(v); self.put_value_back(v);
} }
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} }
@ -393,7 +403,16 @@ impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
{ {
match self.value.take() { match self.value.take() {
Some(t) => { Some(t) => {
let mut dec = Decoder::new(t); let mut dec = {
// Borrowing the key here because Rust doesn't have
// non-lexical borrows yet.
let key = match self.key {
Some(ref key) => &**key,
None => ""
};
self.de.sub_decoder(Some(t), key)
};
let v = try!(de::Deserialize::deserialize(&mut dec)); let v = try!(de::Deserialize::deserialize(&mut dec));
if let Some(t) = dec.toml { if let Some(t) = dec.toml {
self.put_value_back(t); self.put_value_back(t);