mirror of
https://github.com/chronotope/chrono.git
synced 2025-09-28 21:42:01 +00:00
Simplify SerdeError
This commit is contained in:
parent
0b68d19a3e
commit
bbdc332958
@ -147,8 +147,8 @@ pub mod ts_nanoseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::serde_from;
|
||||
use crate::{DateTime, TimeZone, Utc};
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::{DateTime, Utc};
|
||||
|
||||
use super::NanoSecondsTimestampVisitor;
|
||||
|
||||
@ -239,13 +239,11 @@ pub mod ts_nanoseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
Utc.timestamp_opt(
|
||||
value.div_euclid(1_000_000_000),
|
||||
(value.rem_euclid(1_000_000_000)) as u32,
|
||||
),
|
||||
&value,
|
||||
DateTime::from_timestamp(
|
||||
value.div_euclid(1_000_000_000),
|
||||
(value.rem_euclid(1_000_000_000)) as u32,
|
||||
)
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
/// Deserialize a timestamp in nanoseconds since the epoch
|
||||
@ -253,10 +251,8 @@ pub mod ts_nanoseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
Utc.timestamp_opt((value / 1_000_000_000) as i64, (value % 1_000_000_000) as u32),
|
||||
&value,
|
||||
)
|
||||
DateTime::from_timestamp((value / 1_000_000_000) as i64, (value % 1_000_000_000) as u32)
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -447,8 +443,8 @@ pub mod ts_microseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::serde_from;
|
||||
use crate::{DateTime, TimeZone, Utc};
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::{DateTime, Utc};
|
||||
|
||||
use super::MicroSecondsTimestampVisitor;
|
||||
|
||||
@ -529,13 +525,11 @@ pub mod ts_microseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
Utc.timestamp_opt(
|
||||
value.div_euclid(1_000_000),
|
||||
(value.rem_euclid(1_000_000) * 1_000) as u32,
|
||||
),
|
||||
&value,
|
||||
DateTime::from_timestamp(
|
||||
value.div_euclid(1_000_000),
|
||||
(value.rem_euclid(1_000_000) * 1000) as u32,
|
||||
)
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
/// Deserialize a timestamp in milliseconds since the epoch
|
||||
@ -543,10 +537,11 @@ pub mod ts_microseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
Utc.timestamp_opt((value / 1_000_000) as i64, ((value % 1_000_000) * 1_000) as u32),
|
||||
&value,
|
||||
DateTime::from_timestamp(
|
||||
(value / 1_000_000) as i64,
|
||||
((value % 1_000_000) * 1_000) as u32,
|
||||
)
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -726,8 +721,8 @@ pub mod ts_milliseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::serde_from;
|
||||
use crate::{DateTime, TimeZone, Utc};
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::{DateTime, Utc};
|
||||
|
||||
use super::MilliSecondsTimestampVisitor;
|
||||
|
||||
@ -808,7 +803,7 @@ pub mod ts_milliseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(Utc.timestamp_millis_opt(value), &value)
|
||||
DateTime::from_timestamp_millis(value).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
/// Deserialize a timestamp in milliseconds since the epoch
|
||||
@ -816,10 +811,8 @@ pub mod ts_milliseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
Utc.timestamp_opt((value / 1000) as i64, ((value % 1000) * 1_000_000) as u32),
|
||||
&value,
|
||||
)
|
||||
DateTime::from_timestamp((value / 1000) as i64, ((value % 1000) * 1_000_000) as u32)
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1006,8 +999,8 @@ pub mod ts_seconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::serde_from;
|
||||
use crate::{DateTime, LocalResult, TimeZone, Utc};
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::{DateTime, Utc};
|
||||
|
||||
use super::SecondsTimestampVisitor;
|
||||
|
||||
@ -1078,7 +1071,7 @@ pub mod ts_seconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(Utc.timestamp_opt(value, 0), &value)
|
||||
DateTime::from_timestamp(value, 0).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
/// Deserialize a timestamp in seconds since the epoch
|
||||
@ -1086,14 +1079,11 @@ pub mod ts_seconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
serde_from(
|
||||
if value > i64::MAX as u64 {
|
||||
LocalResult::None
|
||||
} else {
|
||||
Utc.timestamp_opt(value as i64, 0)
|
||||
},
|
||||
&value,
|
||||
)
|
||||
if value > i64::MAX as u64 {
|
||||
Err(invalid_ts(value))
|
||||
} else {
|
||||
DateTime::from_timestamp(value as i64, 0).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
42
src/lib.rs
42
src/lib.rs
@ -629,56 +629,30 @@ pub use naive::__BenchYearFlags;
|
||||
/// [2]: https://serde.rs/field-attrs.html#with
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod serde {
|
||||
use crate::offset::LocalResult;
|
||||
use core::fmt;
|
||||
use serde::de;
|
||||
|
||||
pub use super::datetime::serde::*;
|
||||
|
||||
// lik? function to convert a LocalResult into a serde-ish Result
|
||||
pub(crate) fn serde_from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
|
||||
/// Create a custom `de::Error` with `SerdeError::InvalidTimestamp`.
|
||||
pub(crate) fn invalid_ts<E, T>(value: T) -> E
|
||||
where
|
||||
E: de::Error,
|
||||
V: fmt::Display,
|
||||
T: fmt::Display,
|
||||
{
|
||||
match me {
|
||||
LocalResult::None => Err(E::custom(ne_timestamp(ts))),
|
||||
LocalResult::Ambiguous(min, max) => {
|
||||
Err(E::custom(SerdeError::Ambiguous { timestamp: ts, min, max }))
|
||||
}
|
||||
LocalResult::Single(val) => Ok(val),
|
||||
}
|
||||
E::custom(SerdeError::InvalidTimestamp(value))
|
||||
}
|
||||
|
||||
pub(crate) enum SerdeError<V: fmt::Display, D: fmt::Display> {
|
||||
NonExistent { timestamp: V },
|
||||
Ambiguous { timestamp: V, min: D, max: D },
|
||||
enum SerdeError<T: fmt::Display> {
|
||||
InvalidTimestamp(T),
|
||||
}
|
||||
|
||||
/// Construct a [`SerdeError::NonExistent`]
|
||||
pub(crate) fn ne_timestamp<T: fmt::Display>(ts: T) -> SerdeError<T, u8> {
|
||||
SerdeError::NonExistent::<T, u8> { timestamp: ts }
|
||||
}
|
||||
|
||||
impl<V: fmt::Display, D: fmt::Display> fmt::Debug for SerdeError<V, D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "ChronoSerdeError({})", self)
|
||||
}
|
||||
}
|
||||
|
||||
// impl<V: fmt::Display, D: fmt::Debug> core::error::Error for SerdeError<V, D> {}
|
||||
impl<V: fmt::Display, D: fmt::Display> fmt::Display for SerdeError<V, D> {
|
||||
impl<T: fmt::Display> fmt::Display for SerdeError<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
SerdeError::NonExistent { timestamp } => {
|
||||
write!(f, "value is not a legal timestamp: {}", timestamp)
|
||||
SerdeError::InvalidTimestamp(ts) => {
|
||||
write!(f, "value is not a legal timestamp: {}", ts)
|
||||
}
|
||||
SerdeError::Ambiguous { timestamp, min, max } => write!(
|
||||
f,
|
||||
"value is an ambiguous timestamp: {}, could be either of {}, {}",
|
||||
timestamp, min, max
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ pub mod ts_nanoseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::ne_timestamp;
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::NaiveDateTime;
|
||||
|
||||
/// Serialize a datetime into an integer number of nanoseconds since the epoch
|
||||
@ -175,7 +175,7 @@ pub mod ts_nanoseconds {
|
||||
value.div_euclid(1_000_000_000),
|
||||
(value.rem_euclid(1_000_000_000)) as u32,
|
||||
)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
||||
@ -186,7 +186,7 @@ pub mod ts_nanoseconds {
|
||||
(value / 1_000_000_000) as i64,
|
||||
(value % 1_000_000_000) as u32,
|
||||
)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -371,7 +371,7 @@ pub mod ts_microseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::ne_timestamp;
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::NaiveDateTime;
|
||||
|
||||
/// Serialize a datetime into an integer number of microseconds since the epoch
|
||||
@ -450,8 +450,7 @@ pub mod ts_microseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
NaiveDateTime::from_timestamp_micros(value)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
NaiveDateTime::from_timestamp_micros(value).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
||||
@ -462,7 +461,7 @@ pub mod ts_microseconds {
|
||||
(value / 1_000_000) as i64,
|
||||
((value % 1_000_000) * 1_000) as u32,
|
||||
)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -635,7 +634,7 @@ pub mod ts_milliseconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::ne_timestamp;
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::NaiveDateTime;
|
||||
|
||||
/// Serialize a datetime into an integer number of milliseconds since the epoch
|
||||
@ -714,8 +713,7 @@ pub mod ts_milliseconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
NaiveDateTime::from_timestamp_millis(value)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
NaiveDateTime::from_timestamp_millis(value).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
||||
@ -726,7 +724,7 @@ pub mod ts_milliseconds {
|
||||
(value / 1000) as i64,
|
||||
((value % 1000) * 1_000_000) as u32,
|
||||
)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
.ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -895,7 +893,7 @@ pub mod ts_seconds {
|
||||
use core::fmt;
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::serde::ne_timestamp;
|
||||
use crate::serde::invalid_ts;
|
||||
use crate::NaiveDateTime;
|
||||
|
||||
/// Serialize a datetime into an integer number of seconds since the epoch
|
||||
@ -967,16 +965,14 @@ pub mod ts_seconds {
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
NaiveDateTime::from_timestamp_opt(value, 0)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
NaiveDateTime::from_timestamp_opt(value, 0).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
NaiveDateTime::from_timestamp_opt(value as i64, 0)
|
||||
.ok_or_else(|| E::custom(ne_timestamp(value)))
|
||||
NaiveDateTime::from_timestamp_opt(value as i64, 0).ok_or_else(|| invalid_ts(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user