mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 19:31:02 +00:00
Support std::time::SystemTime
This commit is contained in:
@@ -1364,6 +1364,132 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<'de> Deserialize<'de> for SystemTime {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
// Reuse duration
|
||||||
|
enum Field {
|
||||||
|
Secs,
|
||||||
|
Nanos,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Field {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct FieldVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for FieldVisitor {
|
||||||
|
type Value = Field;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
"secs_since_epoch" => Ok(Field::Secs),
|
||||||
|
"nanos_since_epoch" => Ok(Field::Nanos),
|
||||||
|
_ => Err(Error::unknown_field(value, FIELDS)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
b"secs_since_epoch" => Ok(Field::Secs),
|
||||||
|
b"nanos_since_epoch" => Ok(Field::Nanos),
|
||||||
|
_ => {
|
||||||
|
let value = String::from_utf8_lossy(value);
|
||||||
|
Err(Error::unknown_field(&value, FIELDS))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_identifier(FieldVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DurationVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for DurationVisitor {
|
||||||
|
type Value = Duration;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("struct Duration")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
|
||||||
|
where
|
||||||
|
A: SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let secs: u64 = match try!(seq.next_element()) {
|
||||||
|
Some(value) => value,
|
||||||
|
None => {
|
||||||
|
return Err(Error::invalid_length(0, &self));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let nanos: u32 = match try!(seq.next_element()) {
|
||||||
|
Some(value) => value,
|
||||||
|
None => {
|
||||||
|
return Err(Error::invalid_length(1, &self));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(Duration::new(secs, nanos))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
|
||||||
|
where
|
||||||
|
A: MapAccess<'de>,
|
||||||
|
{
|
||||||
|
let mut secs: Option<u64> = None;
|
||||||
|
let mut nanos: Option<u32> = None;
|
||||||
|
while let Some(key) = try!(map.next_key()) {
|
||||||
|
match key {
|
||||||
|
Field::Secs => {
|
||||||
|
if secs.is_some() {
|
||||||
|
return Err(<A::Error as Error>::duplicate_field("secs_since_epoch"));
|
||||||
|
}
|
||||||
|
secs = Some(try!(map.next_value()));
|
||||||
|
}
|
||||||
|
Field::Nanos => {
|
||||||
|
if nanos.is_some() {
|
||||||
|
return Err(<A::Error as Error>::duplicate_field("nanos_since_epoch"));
|
||||||
|
}
|
||||||
|
nanos = Some(try!(map.next_value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let secs = match secs {
|
||||||
|
Some(secs) => secs,
|
||||||
|
None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
|
||||||
|
};
|
||||||
|
let nanos = match nanos {
|
||||||
|
Some(nanos) => nanos,
|
||||||
|
None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
|
||||||
|
};
|
||||||
|
Ok(Duration::new(secs, nanos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
|
||||||
|
let duration = try!(deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor));
|
||||||
|
Ok(UNIX_EPOCH + duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Similar to:
|
// Similar to:
|
||||||
//
|
//
|
||||||
// #[derive(Deserialize)]
|
// #[derive(Deserialize)]
|
||||||
|
|||||||
@@ -94,6 +94,7 @@
|
|||||||
//! - OsString
|
//! - OsString
|
||||||
//! - **Miscellaneous standard library types**:
|
//! - **Miscellaneous standard library types**:
|
||||||
//! - Duration
|
//! - Duration
|
||||||
|
//! - SystemTime
|
||||||
//! - Path
|
//! - Path
|
||||||
//! - PathBuf
|
//! - PathBuf
|
||||||
//! - Range\<T\>
|
//! - Range\<T\>
|
||||||
|
|||||||
+1
-1
@@ -187,7 +187,7 @@ mod lib {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::path::{Path, PathBuf};
|
pub use std::path::{Path, PathBuf};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::time::Duration;
|
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::sync::{Mutex, RwLock};
|
pub use std::sync::{Mutex, RwLock};
|
||||||
|
|
||||||
|
|||||||
@@ -455,6 +455,23 @@ impl Serialize for Duration {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl Serialize for SystemTime {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
use super::SerializeStruct;
|
||||||
|
let duration_since_epoch = self.duration_since(UNIX_EPOCH).expect("SystemTime must be later than UNIX_EPOCH");
|
||||||
|
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
||||||
|
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||||
|
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||||
|
state.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// Serialize a value that implements `Display` as a string, when that string is
|
/// Serialize a value that implements `Display` as a string, when that string is
|
||||||
/// statically known to never have more than a constant `MAX_LEN` bytes.
|
/// statically known to never have more than a constant `MAX_LEN` bytes.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -89,6 +89,7 @@
|
|||||||
//! - OsString
|
//! - OsString
|
||||||
//! - **Miscellaneous standard library types**:
|
//! - **Miscellaneous standard library types**:
|
||||||
//! - Duration
|
//! - Duration
|
||||||
|
//! - SystemTime
|
||||||
//! - Path
|
//! - Path
|
||||||
//! - PathBuf
|
//! - PathBuf
|
||||||
//! - Range\<T\>
|
//! - Range\<T\>
|
||||||
|
|||||||
Reference in New Issue
Block a user