pub mod timestamp {
use serde::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::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(alloc::format!(
"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(alloc::format!(
"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(alloc::format!(
"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::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_second())
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ts) => se.serialize_i64(ts.as_second()),
}
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod millisecond {
use serde::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(alloc::format!(
"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(alloc::format!(
"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(alloc::format!(
"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::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_millisecond())
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ts) => se.serialize_i64(ts.as_millisecond()),
}
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod microsecond {
use serde::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(alloc::format!(
"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(alloc::format!(
"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(alloc::format!(
"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::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i64(timestamp.as_microsecond())
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i64(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ts) => se.serialize_i64(ts.as_microsecond()),
}
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
pub mod nanosecond {
use serde::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(alloc::format!(
"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::Serializer>(
timestamp: &crate::Timestamp,
se: S,
) -> Result<S::Ok, S::Error> {
se.serialize_i128(timestamp.as_nanosecond())
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<crate::Timestamp, D::Error> {
de.deserialize_i128(super::Visitor)
}
}
pub mod optional {
#[inline]
pub fn serialize<S: serde::Serializer>(
timestamp: &Option<crate::Timestamp>,
se: S,
) -> Result<S::Ok, S::Error> {
match *timestamp {
None => se.serialize_none(),
Some(ts) => se.serialize_i128(ts.as_nanosecond()),
}
}
#[inline]
pub fn deserialize<'de, D: serde::Deserializer<'de>>(
de: D,
) -> Result<Option<crate::Timestamp>, D::Error> {
de.deserialize_option(super::super::OptionalVisitor(
super::Visitor,
))
}
}
}
}
#[cfg(test)]
mod tests {
use crate::Timestamp;
#[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);
}
}