Standardize behavior of missing fields
This commit is contained in:
parent
88149fc0c3
commit
42bc63bed8
@ -1061,11 +1061,11 @@ impl Deserialize for Duration {
|
||||
}
|
||||
let secs = match secs {
|
||||
Some(secs) => secs,
|
||||
None => try!(visitor.missing_field("secs")),
|
||||
None => return Err(<V::Error as Error>::missing_field("secs")),
|
||||
};
|
||||
let nanos = match nanos {
|
||||
Some(nanos) => nanos,
|
||||
None => try!(visitor.missing_field("nanos")),
|
||||
None => return Err(<V::Error as Error>::missing_field("nanos")),
|
||||
};
|
||||
Ok(Duration::new(secs, nanos))
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ pub mod impls;
|
||||
pub mod value;
|
||||
mod from_primitive;
|
||||
|
||||
// Helpers used by generated code. Not public API.
|
||||
#[doc(hidden)]
|
||||
pub mod private;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// `Error` is a trait that allows a `Deserialize` to generically create a
|
||||
@ -926,31 +930,6 @@ pub trait MapVisitor {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(0, None)
|
||||
}
|
||||
|
||||
/// Report that the struct has a field that wasn't deserialized. The
|
||||
/// MapVisitor may consider this an error or it may return a default value
|
||||
/// for the field.
|
||||
///
|
||||
/// `Deserialize` implementations should typically use
|
||||
/// `MapVisitor::missing_field` instead.
|
||||
fn missing_field_seed<V>(&mut self, _seed: V, field: &'static str) -> Result<V::Value, Self::Error>
|
||||
where V: DeserializeSeed
|
||||
{
|
||||
Err(Error::missing_field(field))
|
||||
}
|
||||
|
||||
/// Report that the struct has a field that wasn't deserialized. The
|
||||
/// MapVisitor may consider this an error or it may return a default value
|
||||
/// for the field.
|
||||
///
|
||||
/// This method exists as a convenience for `Deserialize` implementations.
|
||||
/// `MapVisitor` implementations should not need to override the default
|
||||
/// behavior.
|
||||
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
|
||||
where V: Deserialize,
|
||||
{
|
||||
self.missing_field_seed(PhantomData, field)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
||||
@ -1004,20 +983,6 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(**self).size_hint()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn missing_field_seed<V>(&mut self, seed: V, field: &'static str) -> Result<V::Value, Self::Error>
|
||||
where V: DeserializeSeed
|
||||
{
|
||||
(**self).missing_field_seed(seed, field)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
|
||||
where V: Deserialize
|
||||
{
|
||||
(**self).missing_field(field)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
40
serde/src/de/private.rs
Normal file
40
serde/src/de/private.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use de::{Deserialize, Deserializer, Error, Visitor};
|
||||
|
||||
/// If the missing field is of type `Option<T>` then treat is as `None`,
|
||||
/// otherwise it is an error.
|
||||
pub fn missing_field<V, E>(field: &'static str) -> Result<V, E>
|
||||
where V: Deserialize,
|
||||
E: Error
|
||||
{
|
||||
struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
|
||||
|
||||
impl<E> Deserializer for MissingFieldDeserializer<E>
|
||||
where E: Error
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn deserialize<V>(self, _visitor: V) -> Result<V::Value, E>
|
||||
where V: Visitor
|
||||
{
|
||||
Err(Error::missing_field(self.0))
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
|
||||
where V: Visitor
|
||||
{
|
||||
visitor.visit_none()
|
||||
}
|
||||
|
||||
forward_to_deserialize! {
|
||||
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
|
||||
string unit seq seq_fixed_size bytes byte_buf map unit_struct
|
||||
newtype_struct tuple_struct struct struct_field tuple enum
|
||||
ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
let deserializer = MissingFieldDeserializer(field, PhantomData);
|
||||
Deserialize::deserialize(deserializer)
|
||||
}
|
@ -928,7 +928,7 @@ fn expr_is_missing(attrs: &attr::Field) -> Tokens {
|
||||
match attrs.deserialize_with() {
|
||||
None => {
|
||||
quote! {
|
||||
try!(visitor.missing_field(#name))
|
||||
try!(_serde::de::private::missing_field(#name))
|
||||
}
|
||||
}
|
||||
Some(_) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user