pub mod duration {
pub mod friendly {
pub mod compact {
use crate::fmt::{friendly, StdFmtWrite};
struct CompactDuration<'a>(&'a crate::SignedDuration);
impl<'a> core::fmt::Display for CompactDuration<'a> {
fn fmt(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
static PRINTER: friendly::SpanPrinter =
friendly::SpanPrinter::new()
.designator(friendly::Designator::Compact);
PRINTER
.print_duration(self.0, StdFmtWrite(f))
.map_err(|_| core::fmt::Error)
}
}
#[inline]
pub fn required<S: serde_core::Serializer>(
duration: &crate::SignedDuration,
se: S,
) -> Result<S::Ok, S::Error> {
se.collect_str(&CompactDuration(duration))
}
#[inline]
pub fn optional<S: serde_core::Serializer>(
duration: &Option<crate::SignedDuration>,
se: S,
) -> Result<S::Ok, S::Error> {
match *duration {
None => se.serialize_none(),
Some(ref duration) => required(duration, se),
}
}
}
}
}
pub mod span {
pub mod friendly {
pub mod compact {
use crate::fmt::{friendly, StdFmtWrite};
struct CompactSpan<'a>(&'a crate::Span);
impl<'a> core::fmt::Display for CompactSpan<'a> {
fn fmt(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
static PRINTER: friendly::SpanPrinter =
friendly::SpanPrinter::new()
.designator(friendly::Designator::Compact);
PRINTER
.print_span(self.0, StdFmtWrite(f))
.map_err(|_| core::fmt::Error)
}
}
#[inline]
pub fn required<S: serde_core::Serializer>(
span: &crate::Span,
se: S,
) -> Result<S::Ok, S::Error> {
se.collect_str(&CompactSpan(span))
}
#[inline]
pub fn optional<S: serde_core::Serializer>(
span: &Option<crate::Span>,
se: S,
) -> Result<S::Ok, S::Error> {
match *span {
None => se.serialize_none(),
Some(ref span) => required(span, se),
}
}
}
}
}
pub mod timestamp {
use serde_core::de;
struct OptionalVisitor<V>(V);
impl<'de, V: de::Visitor<'de, Value = crate::Timestamp>> de::Visitor<'de>
for OptionalVisitor<V>
{
type Value = Option<crate::Timestamp>;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"an integer number of seconds from the Unix epoch or `None`",
)
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(
self,
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_i64(self.0).map(Some)
}
#[inline]
fn visit_none<E: de::Error>(
self,
) -> Result<Option<crate::Timestamp>, E> {
Ok(None)
}
}
pub mod second {
use serde_core::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = crate::Timestamp;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str("an integer number of seconds from the Unix epoch")
}
#[inline]
fn visit_i8<E: de::Error>(
self,
v: i8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u8<E: de::Error>(
self,
v: u8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i16<E: de::Error>(
self,
v: i16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u16<E: de::Error>(
self,
v: u16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i32<E: de::Error>(
self,
v: i32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u32<E: de::Error>(
self,
v: u32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i64<E: de::Error>(
self,
v: i64,
) -> Result<crate::Timestamp, E> {
crate::Timestamp::from_second(v).map_err(de::Error::custom)
}
#[inline]
fn visit_u64<E: de::Error>(
self,
v: u64,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} seconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_i128<E: de::Error>(
self,
v: i128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got signed integer {v} seconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_u128<E: de::Error>(
self,
v: u128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} seconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
}
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_second())
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ref ts) => super::required::serialize(ts, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod millisecond {
use serde_core::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = crate::Timestamp;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"an integer number of milliseconds from the Unix epoch",
)
}
#[inline]
fn visit_i8<E: de::Error>(
self,
v: i8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u8<E: de::Error>(
self,
v: u8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i16<E: de::Error>(
self,
v: i16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u16<E: de::Error>(
self,
v: u16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i32<E: de::Error>(
self,
v: i32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u32<E: de::Error>(
self,
v: u32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i64<E: de::Error>(
self,
v: i64,
) -> Result<crate::Timestamp, E> {
crate::Timestamp::from_millisecond(v)
.map_err(de::Error::custom)
}
#[inline]
fn visit_u64<E: de::Error>(
self,
v: u64,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} milliseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_i128<E: de::Error>(
self,
v: i128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got signed integer {v} milliseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_u128<E: de::Error>(
self,
v: u128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} milliseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
}
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_millisecond())
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ref ts) => super::required::serialize(ts, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod microsecond {
use serde_core::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = crate::Timestamp;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"an integer number of microseconds from the Unix epoch",
)
}
#[inline]
fn visit_i8<E: de::Error>(
self,
v: i8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u8<E: de::Error>(
self,
v: u8,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i16<E: de::Error>(
self,
v: i16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u16<E: de::Error>(
self,
v: u16,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i32<E: de::Error>(
self,
v: i32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_u32<E: de::Error>(
self,
v: u32,
) -> Result<crate::Timestamp, E> {
self.visit_i64(i64::from(v))
}
#[inline]
fn visit_i64<E: de::Error>(
self,
v: i64,
) -> Result<crate::Timestamp, E> {
crate::Timestamp::from_microsecond(v)
.map_err(de::Error::custom)
}
#[inline]
fn visit_u64<E: de::Error>(
self,
v: u64,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} microseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_i128<E: de::Error>(
self,
v: i128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got signed integer {v} microseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
#[inline]
fn visit_u128<E: de::Error>(
self,
v: u128,
) -> Result<crate::Timestamp, E> {
let v = i64::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} microseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i64(v)
}
}
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_microsecond())
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ref ts) => super::required::serialize(ts, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod nanosecond {
use serde_core::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = crate::Timestamp;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"an integer number of nanoseconds from the Unix epoch",
)
}
#[inline]
fn visit_i64<E: de::Error>(
self,
v: i64,
) -> Result<crate::Timestamp, E> {
self.visit_i128(i128::from(v))
}
#[inline]
fn visit_u64<E: de::Error>(
self,
v: u64,
) -> Result<crate::Timestamp, E> {
self.visit_u128(u128::from(v))
}
#[inline]
fn visit_i128<E: de::Error>(
self,
v: i128,
) -> Result<crate::Timestamp, E> {
crate::Timestamp::from_nanosecond(v).map_err(de::Error::custom)
}
#[inline]
fn visit_u128<E: de::Error>(
self,
v: u128,
) -> Result<crate::Timestamp, E> {
let v = i128::try_from(v).map_err(|_| {
de::Error::custom(format_args!(
"got unsigned integer {v} nanoseconds, \
which is too big to fit in a Jiff `Timestamp`",
))
})?;
self.visit_i128(v)
}
}
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i128(timestamp.as_nanosecond())
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i128(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ref ts) => super::required::serialize(ts, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
}
pub mod tz {
use serde_core::de;
use crate::fmt::{temporal, StdFmtWrite};
struct TemporalTimeZone<'a>(&'a crate::tz::TimeZone);
impl<'a> core::fmt::Display for TemporalTimeZone<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
static PRINTER: temporal::DateTimePrinter =
temporal::DateTimePrinter::new();
PRINTER
.print_time_zone(self.0, StdFmtWrite(f))
.map_err(|_| core::fmt::Error)
}
}
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = crate::tz::TimeZone;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"a string representing a time zone via an \
IANA time zone identifier, fixed offset from UTC \
or a POSIX time zone string",
)
}
#[inline]
fn visit_bytes<E: de::Error>(
self,
value: &[u8],
) -> Result<crate::tz::TimeZone, E> {
static PARSER: temporal::DateTimeParser =
temporal::DateTimeParser::new();
PARSER.parse_time_zone(value).map_err(de::Error::custom)
}
#[inline]
fn visit_str<E: de::Error>(
self,
value: &str,
) -> Result<crate::tz::TimeZone, E> {
self.visit_bytes(value.as_bytes())
}
}
struct OptionalVisitor<V>(V);
impl<'de, V: de::Visitor<'de, Value = crate::tz::TimeZone>>
de::Visitor<'de> for OptionalVisitor<V>
{
type Value = Option<crate::tz::TimeZone>;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str(
"a string representing a time zone via an \
IANA time zone identifier, fixed offset from UTC \
or a POSIX time zone string",
)
}
#[inline]
fn visit_some<D: de::Deserializer<'de>>(
self,
de: D,
) -> Result<Option<crate::tz::TimeZone>, D::Error> {
de.deserialize_str(self.0).map(Some)
}
#[inline]
fn visit_none<E: de::Error>(
self,
) -> Result<Option<crate::tz::TimeZone>, E> {
Ok(None)
}
}
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
tz: &crate::tz::TimeZone,
se: S,
) -> Result<S::Ok, S::Error> {
if !tz.has_succinct_serialization() {
return Err(<S::Error as serde_core::ser::Error>::custom(
"time zones without IANA identifiers that aren't either \
fixed offsets or a POSIX time zone can't be serialized \
(this typically occurs when this is a system time zone \
derived from `/etc/localtime` on Unix systems that \
isn't symlinked to an entry in `/usr/share/zoneinfo)",
));
}
se.collect_str(&super::TemporalTimeZone(tz))
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<crate::tz::TimeZone, D::Error> {
de.deserialize_str(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
tz: &Option<crate::tz::TimeZone>,
se: S,
) -> Result<S::Ok, S::Error> {
match *tz {
None => se.serialize_none(),
Some(ref tz) => super::required::serialize(tz, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::tz::TimeZone>, D::Error> {
de.deserialize_option(super::OptionalVisitor(super::Visitor))
}
}
}
pub mod unsigned_duration {
pub mod friendly {
pub mod compact {
pub mod required {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
duration: &core::time::Duration,
se: S,
) -> Result<S::Ok, S::Error> {
se.collect_str(&super::DisplayFriendlyCompact(duration))
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<core::time::Duration, D::Error> {
super::super::super::required::deserialize(de)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde_core::Serializer>(
duration: &Option<core::time::Duration>,
se: S,
) -> Result<S::Ok, S::Error> {
match *duration {
None => se.serialize_none(),
Some(ref duration) => {
super::required::serialize(duration, se)
}
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<core::time::Duration>, D::Error>
{
super::super::super::optional::deserialize(de)
}
}
struct DisplayFriendlyCompact<'a>(&'a core::time::Duration);
impl<'a> core::fmt::Display for DisplayFriendlyCompact<'a> {
fn fmt(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
use crate::fmt::{
friendly::{Designator, SpanPrinter},
StdFmtWrite,
};
static PRINTER: SpanPrinter =
SpanPrinter::new().designator(Designator::Compact);
PRINTER
.print_unsigned_duration(self.0, StdFmtWrite(f))
.map_err(|_| core::fmt::Error)
}
}
}
}
pub mod required {
pub(super) struct Visitor;
impl<'de> serde_core::de::Visitor<'de> for Visitor {
type Value = core::time::Duration;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str("an unsigned duration string")
}
#[inline]
fn visit_bytes<E: serde_core::de::Error>(
self,
value: &[u8],
) -> Result<core::time::Duration, E> {
super::parse_iso_or_friendly(value)
.map_err(serde_core::de::Error::custom)
}
#[inline]
fn visit_str<E: serde_core::de::Error>(
self,
value: &str,
) -> Result<core::time::Duration, E> {
self.visit_bytes(value.as_bytes())
}
}
#[inline]
pub fn serialize<S: serde_core::Serializer>(
duration: &core::time::Duration,
se: S,
) -> Result<S::Ok, S::Error> {
se.collect_str(&super::DisplayISO8601(duration))
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<core::time::Duration, D::Error> {
de.deserialize_str(Visitor)
}
}
pub mod optional {
struct Visitor<V>(V);
impl<
'de,
V: serde_core::de::Visitor<'de, Value = core::time::Duration>,
> serde_core::de::Visitor<'de> for Visitor<V>
{
type Value = Option<core::time::Duration>;
fn expecting(
&self,
f: &mut core::fmt::Formatter,
) -> core::fmt::Result {
f.write_str("an unsigned duration string")
}
#[inline]
fn visit_some<D: serde_core::de::Deserializer<'de>>(
self,
de: D,
) -> Result<Option<core::time::Duration>, D::Error> {
de.deserialize_str(self.0).map(Some)
}
#[inline]
fn visit_none<E: serde_core::de::Error>(
self,
) -> Result<Option<core::time::Duration>, E> {
Ok(None)
}
}
#[inline]
pub fn serialize<S: serde_core::Serializer>(
duration: &Option<core::time::Duration>,
se: S,
) -> Result<S::Ok, S::Error> {
match *duration {
None => se.serialize_none(),
Some(ref duration) => super::required::serialize(duration, se),
}
}
#[inline]
pub fn deserialize<'de, D: serde_core::Deserializer<'de>>(
de: D,
) -> Result<Option<core::time::Duration>, D::Error> {
de.deserialize_option(Visitor(super::required::Visitor))
}
}
struct DisplayISO8601<'a>(&'a core::time::Duration);
impl<'a> core::fmt::Display for DisplayISO8601<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use crate::fmt::temporal::SpanPrinter;
static PRINTER: SpanPrinter = SpanPrinter::new();
PRINTER
.print_unsigned_duration(self.0, crate::fmt::StdFmtWrite(f))
.map_err(|_| core::fmt::Error)
}
}
#[cfg_attr(feature = "perf-inline", inline(always))]
fn parse_iso_or_friendly(
bytes: &[u8],
) -> Result<core::time::Duration, crate::Error> {
let Some((&byte, tail)) = bytes.split_first() else {
return Err(crate::Error::from(
crate::error::fmt::Error::HybridDurationEmpty,
));
};
let mut first = byte;
if first == b'+' || first == b'-' {
let Some(&byte) = tail.first() else {
return Err(crate::Error::from(
crate::error::fmt::Error::HybridDurationPrefix {
sign: first,
},
));
};
first = byte;
}
let dur = if first == b'P' || first == b'p' {
crate::fmt::temporal::DEFAULT_SPAN_PARSER
.parse_unsigned_duration(bytes)
} else {
crate::fmt::friendly::DEFAULT_SPAN_PARSER
.parse_unsigned_duration(bytes)
}?;
Ok(dur)
}
}
#[cfg(test)]
mod tests {
use crate::{
span::span_eq, SignedDuration, Span, SpanFieldwise, Timestamp, ToSpan,
};
use core::time::Duration as UnsignedDuration;
#[test]
fn duration_friendly_compact_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
serialize_with = "crate::fmt::serde::duration::friendly::compact::required"
)]
duration: SignedDuration,
}
let json = r#"{"duration":"36 hours 1100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
SignedDuration::new(36 * 60 * 60 + 1, 100_000_000)
);
let expected = r#"{"duration":"36h 1s 100ms"}"#;
assert_eq!(serde_json::to_string(&got).unwrap(), expected);
}
#[test]
fn duration_friendly_compact_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
serialize_with = "crate::fmt::serde::duration::friendly::compact::optional"
)]
duration: Option<SignedDuration>,
}
let json = r#"{"duration":"36 hours 1100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
Some(SignedDuration::new(36 * 60 * 60 + 1, 100_000_000))
);
let expected = r#"{"duration":"36h 1s 100ms"}"#;
assert_eq!(serde_json::to_string(&got).unwrap(), expected);
}
#[test]
fn unsigned_duration_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(with = "crate::fmt::serde::unsigned_duration::required")]
duration: UnsignedDuration,
}
let json = r#"{"duration":"PT36H1.1S"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
UnsignedDuration::new(36 * 60 * 60 + 1, 100_000_000)
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"duration":"PT18446744073709551615S"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
UnsignedDuration::new(18446744073709551615, 0)
);
let expected = r#"{"duration":"PT5124095576030431H15S"}"#;
assert_eq!(serde_json::to_string(&got).unwrap(), expected);
}
#[test]
fn unsigned_duration_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(with = "crate::fmt::serde::unsigned_duration::optional")]
duration: Option<UnsignedDuration>,
}
let json = r#"{"duration":"PT36H1.1S"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
Some(UnsignedDuration::new(36 * 60 * 60 + 1, 100_000_000))
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"duration":null}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(got.duration, None,);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn unsigned_duration_compact_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::unsigned_duration::friendly::compact::required"
)]
duration: UnsignedDuration,
}
let json = r#"{"duration":"36h 1s 100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
UnsignedDuration::new(36 * 60 * 60 + 1, 100_000_000)
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn unsigned_duration_compact_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::unsigned_duration::friendly::compact::optional"
)]
duration: Option<UnsignedDuration>,
}
let json = r#"{"duration":"36h 1s 100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.duration,
Some(UnsignedDuration::new(36 * 60 * 60 + 1, 100_000_000))
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn span_friendly_compact_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
serialize_with = "crate::fmt::serde::span::friendly::compact::required"
)]
span: Span,
}
let json = r#"{"span":"1 year 2 months 36 hours 1100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
span_eq!(got.span, 1.year().months(2).hours(36).milliseconds(1100));
let expected = r#"{"span":"1y 2mo 36h 1100ms"}"#;
assert_eq!(serde_json::to_string(&got).unwrap(), expected);
}
#[test]
fn span_friendly_compact_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
serialize_with = "crate::fmt::serde::span::friendly::compact::optional"
)]
span: Option<Span>,
}
let json = r#"{"span":"1 year 2 months 36 hours 1100ms"}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.span.map(SpanFieldwise),
Some(1.year().months(2).hours(36).milliseconds(1100).fieldwise())
);
let expected = r#"{"span":"1y 2mo 36h 1100ms"}"#;
assert_eq!(serde_json::to_string(&got).unwrap(), expected);
}
#[test]
fn timestamp_second_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(with = "crate::fmt::serde::timestamp::second::required")]
ts: Timestamp,
}
let json = r#"{"ts":1517644800}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(got.ts, Timestamp::from_second(1517644800).unwrap());
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_second_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(with = "crate::fmt::serde::timestamp::second::optional")]
ts: Option<Timestamp>,
}
let json = r#"{"ts":1517644800}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(got.ts, Some(Timestamp::from_second(1517644800).unwrap()));
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_millisecond_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::millisecond::required"
)]
ts: Timestamp,
}
let json = r#"{"ts":1517644800000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_millisecond(1517644800_000).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_millisecond(1517644800_123).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_millisecond_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::millisecond::optional"
)]
ts: Option<Timestamp>,
}
let json = r#"{"ts":1517644800000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_millisecond(1517644800_000).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_millisecond(1517644800_123).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_microsecond_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::microsecond::required"
)]
ts: Timestamp,
}
let json = r#"{"ts":1517644800000000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_microsecond(1517644800_000000).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123456}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_microsecond(1517644800_123456).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_microsecond_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::microsecond::optional"
)]
ts: Option<Timestamp>,
}
let json = r#"{"ts":1517644800000000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_microsecond(1517644800_000000).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123456}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_microsecond(1517644800_123456).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_nanosecond_required() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::nanosecond::required"
)]
ts: Timestamp,
}
let json = r#"{"ts":1517644800000000000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_nanosecond(1517644800_000000000).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123456789}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Timestamp::from_nanosecond(1517644800_123456789).unwrap()
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
#[test]
fn timestamp_nanosecond_optional() {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
struct Data {
#[serde(
with = "crate::fmt::serde::timestamp::nanosecond::optional"
)]
ts: Option<Timestamp>,
}
let json = r#"{"ts":1517644800000000000}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_nanosecond(1517644800_000000000).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
let json = r#"{"ts":1517644800123456789}"#;
let got: Data = serde_json::from_str(&json).unwrap();
assert_eq!(
got.ts,
Some(Timestamp::from_nanosecond(1517644800_123456789).unwrap())
);
assert_eq!(serde_json::to_string(&got).unwrap(), json);
}
}