pub struct DurationSeconds<FORMAT: Format = u64, STRICTNESS: Strictness = Strict>(_);
Expand description

De/Serialize Durations as number of seconds.

De/serialize durations as number of seconds with subsecond precision. Subsecond precision is only supported for DurationSecondsWithFrac, but not for DurationSeconds. You can configure the serialization format between integers, floats, and stringified numbers with the FORMAT specifier and configure the deserialization with the STRICTNESS specifier.

The STRICTNESS specifier can either be formats::Strict or formats::Flexible and defaults to formats::Strict. formats::Strict means that deserialization only supports the type given in FORMAT, e.g., if FORMAT is u64 deserialization from a f64 will error. formats::Flexible means that deserialization will perform a best effort to extract the correct duration and allows deserialization from any type. For example, deserializing DurationSeconds<f64, Flexible> will discard any subsecond precision during deserialization from f64 and will parse a String as an integer number.

This type also supports chrono::Duration with the chrono_0_4-feature flag. This type also supports time::Duration with the time_0_3-feature flag.

Duration TypeConverterAvailable FORMATs
std::time::DurationDurationSecondsu64, f64, String
std::time::DurationDurationSecondsWithFracf64, String
chrono::DurationDurationSecondsi64, f64, String
chrono::DurationDurationSecondsWithFracf64, String
time::DurationDurationSecondsi64, f64, String
time::DurationDurationSecondsWithFracf64, String

Examples

use std::time::Duration;

#[serde_as]
#[derive(Deserialize, Serialize)]
struct Durations {
    #[serde_as(as = "DurationSeconds<u64>")]
    d_u64: Duration,
    #[serde_as(as = "DurationSeconds<f64>")]
    d_f64: Duration,
    #[serde_as(as = "DurationSeconds<String>")]
    d_string: Duration,
};

// Serialization
// See how the values get rounded, since subsecond precision is not allowed.

let d = Durations {
    d_u64: Duration::new(12345, 0), // Create from seconds and nanoseconds
    d_f64: Duration::new(12345, 500_000_000),
    d_string: Duration::new(12345, 999_999_999),
};
// Observe the different data types
let expected = json!({
    "d_u64": 12345,
    "d_f64": 12346.0,
    "d_string": "12346",
});
assert_eq!(expected, serde_json::to_value(&d).unwrap());

// Deserialization works too
// Subsecond precision in numbers will be rounded away

let json = json!({
    "d_u64": 12345,
    "d_f64": 12345.5,
    "d_string": "12346",
});
let expected = Durations {
    d_u64: Duration::new(12345, 0), // Create from seconds and nanoseconds
    d_f64: Duration::new(12346, 0),
    d_string: Duration::new(12346, 0),
};
assert_eq!(expected, serde_json::from_value(json).unwrap());

chrono::Duration is also supported when using the chrono_0_4 feature. It is a signed duration, thus can be de/serialized as an i64 instead of a u64.

use chrono::Duration;

#[serde_as]
#[derive(Deserialize, Serialize)]
struct Durations {
    #[serde_as(as = "DurationSeconds<i64>")]
    d_i64: Duration,
    #[serde_as(as = "DurationSeconds<f64>")]
    d_f64: Duration,
    #[serde_as(as = "DurationSeconds<String>")]
    d_string: Duration,
};

// Serialization
// See how the values get rounded, since subsecond precision is not allowed.

let d = Durations {
    d_i64: Duration::seconds(-12345),
    d_f64: Duration::seconds(-12345) + Duration::milliseconds(500),
    d_string: Duration::seconds(12345) + Duration::nanoseconds(999_999_999),
};
// Observe the different data types
let expected = json!({
    "d_i64": -12345,
    "d_f64": -12345.0,
    "d_string": "12346",
});
assert_eq!(expected, serde_json::to_value(&d).unwrap());

// Deserialization works too
// Subsecond precision in numbers will be rounded away

let json = json!({
    "d_i64": -12345,
    "d_f64": -12345.5,
    "d_string": "12346",
});
let expected = Durations {
    d_i64: Duration::seconds(-12345),
    d_f64: Duration::seconds(-12346),
    d_string: Duration::seconds(12346),
};
assert_eq!(expected, serde_json::from_value(json).unwrap());

Trait Implementations§

source§

impl<'de, FORMAT> DeserializeAs<'de, Duration> for DurationSeconds<FORMAT, Flexible>where FORMAT: Format,

Available on crate feature time_0_3 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Time03Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de, FORMAT> DeserializeAs<'de, Duration> for DurationSeconds<FORMAT, Flexible>where FORMAT: Format,

source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de, FORMAT> DeserializeAs<'de, Duration> for DurationSeconds<FORMAT, Flexible>where FORMAT: Format,

Available on crate feature chrono_0_4 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<String, Strict>

source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<String, Strict>

Available on crate feature time_0_3 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Time03Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<String, Strict>

Available on crate feature chrono_0_4 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<f64, Strict>

source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<f64, Strict>

Available on crate feature time_0_3 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Time03Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<f64, Strict>

Available on crate feature chrono_0_4 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<i64, Strict>

Available on crate feature chrono_0_4 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<i64, Strict>

Available on crate feature time_0_3 only.
source§

fn deserialize_as<D>(deserializer: D) -> Result<Time03Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<'de> DeserializeAs<'de, Duration> for DurationSeconds<u64, Strict>

source§

fn deserialize_as<D>(deserializer: D) -> Result<Duration, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<String, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature time_0_3 only.
source§

fn serialize_as<S>( source: &Time03Duration, serializer: S ) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<String, STRICTNESS>where STRICTNESS: Strictness,

source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<String, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature chrono_0_4 only.
source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<f64, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature time_0_3 only.
source§

fn serialize_as<S>( source: &Time03Duration, serializer: S ) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<f64, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature chrono_0_4 only.
source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<f64, STRICTNESS>where STRICTNESS: Strictness,

source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<i64, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature time_0_3 only.
source§

fn serialize_as<S>( source: &Time03Duration, serializer: S ) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<i64, STRICTNESS>where STRICTNESS: Strictness,

Available on crate feature chrono_0_4 only.
source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.
source§

impl<STRICTNESS> SerializeAs<Duration> for DurationSeconds<u64, STRICTNESS>where STRICTNESS: Strictness,

source§

fn serialize_as<S>(source: &Duration, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer.

Auto Trait Implementations§

§

impl<FORMAT, STRICTNESS> RefUnwindSafe for DurationSeconds<FORMAT, STRICTNESS>where FORMAT: RefUnwindSafe, STRICTNESS: RefUnwindSafe,

§

impl<FORMAT, STRICTNESS> Send for DurationSeconds<FORMAT, STRICTNESS>where FORMAT: Send, STRICTNESS: Send,

§

impl<FORMAT, STRICTNESS> Sync for DurationSeconds<FORMAT, STRICTNESS>where FORMAT: Sync, STRICTNESS: Sync,

§

impl<FORMAT, STRICTNESS> Unpin for DurationSeconds<FORMAT, STRICTNESS>where FORMAT: Unpin, STRICTNESS: Unpin,

§

impl<FORMAT, STRICTNESS> UnwindSafe for DurationSeconds<FORMAT, STRICTNESS>where FORMAT: UnwindSafe, STRICTNESS: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.