mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-12 22:31:02 +00:00
Standardize behavior of missing fields
This commit is contained in:
@@ -1061,11 +1061,11 @@ impl Deserialize for Duration {
|
|||||||
}
|
}
|
||||||
let secs = match secs {
|
let secs = match secs {
|
||||||
Some(secs) => secs,
|
Some(secs) => secs,
|
||||||
None => try!(visitor.missing_field("secs")),
|
None => return Err(<V::Error as Error>::missing_field("secs")),
|
||||||
};
|
};
|
||||||
let nanos = match nanos {
|
let nanos = match nanos {
|
||||||
Some(nanos) => 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))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-39
@@ -17,6 +17,10 @@ pub mod impls;
|
|||||||
pub mod value;
|
pub mod value;
|
||||||
mod from_primitive;
|
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
|
/// `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>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
(0, None)
|
(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 {
|
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>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
(**self).size_hint()
|
(**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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -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() {
|
match attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
try!(visitor.missing_field(#name))
|
try!(_serde::de::private::missing_field(#name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user