Convert timestamp fields to DateTime's
This commit is contained in:
parent
f876f25a2c
commit
d1b3a9ad9e
|
@ -11,7 +11,7 @@ use std::fmt::Debug;
|
||||||
use crate::types::Shared;
|
use crate::types::Shared;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{GuildMember, User},
|
entities::{GuildMember, User},
|
||||||
utils::Snowflake,
|
utils::{Snowflake, serde::*},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
|
@ -60,6 +60,7 @@ pub struct Channel {
|
||||||
pub icon: Option<String>,
|
pub icon: Option<String>,
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub last_message_id: Option<Snowflake>,
|
pub last_message_id: Option<Snowflake>,
|
||||||
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
pub last_pin_timestamp: Option<DateTime<Utc>>,
|
pub last_pin_timestamp: Option<DateTime<Utc>>,
|
||||||
pub managed: Option<bool>,
|
pub managed: Option<bool>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
|
@ -160,10 +161,12 @@ pub struct PermissionOverwrite {
|
||||||
pub struct ThreadMetadata {
|
pub struct ThreadMetadata {
|
||||||
pub archived: bool,
|
pub archived: bool,
|
||||||
pub auto_archive_duration: i32,
|
pub auto_archive_duration: i32,
|
||||||
pub archive_timestamp: String,
|
#[serde(with = "ts_seconds_str")]
|
||||||
|
pub archive_timestamp: DateTime<Utc>,
|
||||||
pub locked: bool,
|
pub locked: bool,
|
||||||
pub invitable: Option<bool>,
|
pub invitable: Option<bool>,
|
||||||
pub create_timestamp: Option<String>,
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub create_timestamp: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
||||||
|
@ -172,7 +175,8 @@ pub struct ThreadMetadata {
|
||||||
pub struct ThreadMember {
|
pub struct ThreadMember {
|
||||||
pub id: Option<Snowflake>,
|
pub id: Option<Snowflake>,
|
||||||
pub user_id: Option<Snowflake>,
|
pub user_id: Option<Snowflake>,
|
||||||
pub join_timestamp: Option<String>,
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub join_timestamp: Option<DateTime<Utc>>,
|
||||||
pub flags: Option<u64>,
|
pub flags: Option<u64>,
|
||||||
pub member: Option<Shared<GuildMember>>,
|
pub member: Option<Shared<GuildMember>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::types::types::guild_configuration::GuildFeaturesList;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook},
|
entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook},
|
||||||
interfaces::WelcomeScreenObject,
|
interfaces::WelcomeScreenObject,
|
||||||
utils::Snowflake,
|
utils::{Snowflake, serde::*},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PublicUser;
|
use super::PublicUser;
|
||||||
|
@ -67,7 +67,8 @@ pub struct Guild {
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub invites: Option<Vec<GuildInvite>>,
|
pub invites: Option<Vec<GuildInvite>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub joined_at: Option<String>,
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub joined_at: Option<DateTime<Utc>>,
|
||||||
pub large: Option<bool>,
|
pub large: Option<bool>,
|
||||||
pub max_members: Option<i32>,
|
pub max_members: Option<i32>,
|
||||||
pub max_presences: Option<i32>,
|
pub max_presences: Option<i32>,
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::Shared;
|
use crate::types::Shared;
|
||||||
use crate::types::{entities::PublicUser, Snowflake};
|
use crate::types::{entities::PublicUser, Snowflake};
|
||||||
|
use crate::types::utils::serde::*;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Default, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Default, Serialize, Clone)]
|
||||||
/// Represents a participating user in a guild.
|
/// Represents a participating user in a guild.
|
||||||
|
@ -17,12 +19,14 @@ pub struct GuildMember {
|
||||||
pub nick: Option<String>,
|
pub nick: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<String>,
|
||||||
pub roles: Vec<Snowflake>,
|
pub roles: Vec<Snowflake>,
|
||||||
pub joined_at: String,
|
#[serde(with = "ts_seconds_str")]
|
||||||
|
pub joined_at: DateTime<Utc>,
|
||||||
pub premium_since: Option<String>,
|
pub premium_since: Option<String>,
|
||||||
pub deaf: bool,
|
pub deaf: bool,
|
||||||
pub mute: bool,
|
pub mute: bool,
|
||||||
pub flags: Option<i32>,
|
pub flags: Option<i32>,
|
||||||
pub pending: Option<bool>,
|
pub pending: Option<bool>,
|
||||||
pub permissions: Option<String>,
|
pub permissions: Option<String>,
|
||||||
pub communication_disabled_until: Option<String>,
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub communication_disabled_until: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
|
@ -10,7 +11,7 @@ use crate::types::{
|
||||||
Application, Attachment, Channel, Emoji, GuildMember, PublicUser, RoleSubscriptionData,
|
Application, Attachment, Channel, Emoji, GuildMember, PublicUser, RoleSubscriptionData,
|
||||||
Sticker, StickerItem, User,
|
Sticker, StickerItem, User,
|
||||||
},
|
},
|
||||||
utils::Snowflake,
|
utils::{Snowflake, serde::*},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
|
||||||
|
@ -25,8 +26,10 @@ pub struct Message {
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub author: Option<PublicUser>,
|
pub author: Option<PublicUser>,
|
||||||
pub content: Option<String>,
|
pub content: Option<String>,
|
||||||
pub timestamp: String,
|
#[serde(with = "ts_seconds_str")]
|
||||||
pub edited_timestamp: Option<String>,
|
pub timestamp: DateTime<Utc>,
|
||||||
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub edited_timestamp: Option<DateTime<Utc>>,
|
||||||
pub tts: Option<bool>,
|
pub tts: Option<bool>,
|
||||||
pub mention_everyone: bool,
|
pub mention_everyone: bool,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::types::utils::serde::ts_seconds_option_str;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
@ -13,7 +15,8 @@ pub struct RegisterSchema {
|
||||||
pub email: Option<String>,
|
pub email: Option<String>,
|
||||||
pub fingerprint: Option<String>,
|
pub fingerprint: Option<String>,
|
||||||
pub invite: Option<String>,
|
pub invite: Option<String>,
|
||||||
pub date_of_birth: Option<String>,
|
#[serde(with = "ts_seconds_option_str")]
|
||||||
|
pub date_of_birth: Option<DateTime<Utc>>,
|
||||||
pub gift_code_sku_id: Option<String>,
|
pub gift_code_sku_id: Option<String>,
|
||||||
pub captcha_key: Option<String>,
|
pub captcha_key: Option<String>,
|
||||||
pub promotional_email_opt_in: Option<bool>,
|
pub promotional_email_opt_in: Option<bool>,
|
||||||
|
|
|
@ -11,3 +11,5 @@ pub mod jwt;
|
||||||
mod regexes;
|
mod regexes;
|
||||||
mod rights;
|
mod rights;
|
||||||
mod snowflake;
|
mod snowflake;
|
||||||
|
pub mod serde;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
use core::fmt;
|
||||||
|
use chrono::{LocalResult, NaiveDateTime};
|
||||||
|
use serde::de;
|
||||||
|
use chrono::serde::ts_seconds;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SecondsStringTimestampVisitor;
|
||||||
|
|
||||||
|
|
||||||
|
/// Ser/de to/from timestamps in seconds
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`'s `with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{TimeZone, DateTime, Utc};
|
||||||
|
/// # use serde::{Deserialize, Serialize};
|
||||||
|
/// use chrono::serde::ts_seconds;
|
||||||
|
/// #[derive(Deserialize, Serialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(with = "ts_seconds_str")]
|
||||||
|
/// time: DateTime<Utc>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let time = Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap();
|
||||||
|
/// let my_s = S {
|
||||||
|
/// time: time.clone(),
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// let as_string = serde_json::to_string(&my_s)?;
|
||||||
|
/// assert_eq!(as_string, r#"{"time":"1431684000"}"#);
|
||||||
|
/// let my_s: S = serde_json::from_str(&as_string)?;
|
||||||
|
/// assert_eq!(my_s.time, time);
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
pub mod ts_seconds_str {
|
||||||
|
use core::fmt;
|
||||||
|
use chrono::{DateTime, LocalResult, Utc};
|
||||||
|
use super::SecondsStringTimestampVisitor;
|
||||||
|
use serde::{de, ser};
|
||||||
|
use chrono::TimeZone;
|
||||||
|
use super::serde_from;
|
||||||
|
|
||||||
|
/// Serialize a UTC datetime into an integer number of seconds since the epoch
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`s `serialize_with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{TimeZone, DateTime, Utc};
|
||||||
|
/// # use serde::Serialize;
|
||||||
|
/// use chrono::serde::ts_seconds::serialize as to_ts;
|
||||||
|
/// #[derive(Serialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(serialize_with = "ts_seconds_str")]
|
||||||
|
/// time: DateTime<Utc>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_s = S {
|
||||||
|
/// time: Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap(),
|
||||||
|
/// };
|
||||||
|
/// let as_string = serde_json::to_string(&my_s)?;
|
||||||
|
/// assert_eq!(as_string, r#"{"time":"1431684000"}"#);
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
pub fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&format!("{}", dt.timestamp()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a `DateTime` from a seconds timestamp
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`s `deserialize_with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
/// # use serde::Deserialize;
|
||||||
|
/// use chrono::serde::ts_seconds::deserialize as from_ts;
|
||||||
|
/// #[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(deserialize_with = "ts_seconds_str")]
|
||||||
|
/// time: DateTime<Utc>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_s: S = serde_json::from_str(r#"{ "time": "1431684000" }"#)?;
|
||||||
|
/// assert_eq!(my_s, S { time: Utc.timestamp_opt(1431684000, 0).unwrap() });
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error>
|
||||||
|
where
|
||||||
|
D: de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
d.deserialize_str(SecondsStringTimestampVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> de::Visitor<'de> for SecondsStringTimestampVisitor {
|
||||||
|
type Value = DateTime<Utc>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a unix timestamp in seconds")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a timestamp in seconds since the epoch
|
||||||
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
serde_from(Utc.timestamp_opt(value.parse::<i64>().map_err(|e| E::custom(e))?, 0), &value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ser/de to/from optional timestamps in seconds
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`'s `with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{TimeZone, DateTime, Utc};
|
||||||
|
/// # use serde::{Deserialize, Serialize};
|
||||||
|
/// use chrono::serde::ts_seconds_option;
|
||||||
|
/// #[derive(Deserialize, Serialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(with = "ts_seconds_option_str")]
|
||||||
|
/// time: Option<DateTime<Utc>>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let time = Some(Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap());
|
||||||
|
/// let my_s = S {
|
||||||
|
/// time: time.clone(),
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// let as_string = serde_json::to_string(&my_s)?;
|
||||||
|
/// assert_eq!(as_string, r#"{"time":"1431684000"}"#);
|
||||||
|
/// let my_s: S = serde_json::from_str(&as_string)?;
|
||||||
|
/// assert_eq!(my_s.time, time);
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
pub mod ts_seconds_option_str {
|
||||||
|
use core::fmt;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{de, ser};
|
||||||
|
use super::SecondsStringTimestampVisitor;
|
||||||
|
|
||||||
|
/// Serialize a UTC datetime into an integer number of seconds since the epoch or none
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`s `serialize_with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{TimeZone, DateTime, Utc};
|
||||||
|
/// # use serde::Serialize;
|
||||||
|
/// use chrono::serde::ts_seconds_option::serialize as to_tsopt;
|
||||||
|
/// #[derive(Serialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(serialize_with = "ts_seconds_option_str")]
|
||||||
|
/// time: Option<DateTime<Utc>>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_s = S {
|
||||||
|
/// time: Some(Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap()),
|
||||||
|
/// };
|
||||||
|
/// let as_string = serde_json::to_string(&my_s)?;
|
||||||
|
/// assert_eq!(as_string, r#"{"time":"1431684000"}"#);
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: ser::Serializer,
|
||||||
|
{
|
||||||
|
match *opt {
|
||||||
|
Some(ref dt) => serializer.serialize_some(&dt.timestamp().to_string()),
|
||||||
|
None => serializer.serialize_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a `DateTime` from a seconds timestamp or none
|
||||||
|
///
|
||||||
|
/// Intended for use with `serde`s `deserialize_with` attribute.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
/// # use serde::Deserialize;
|
||||||
|
/// use chrono::serde::ts_seconds_option::deserialize as from_tsopt;
|
||||||
|
/// #[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
/// struct S {
|
||||||
|
/// #[serde(deserialize_with = "ts_seconds_option_str")]
|
||||||
|
/// time: Option<DateTime<Utc>>
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let my_s: S = serde_json::from_str(r#"{ "time": "1431684000" }"#)?;
|
||||||
|
/// assert_eq!(my_s, S { time: Utc.timestamp_opt(1431684000, 0).single() });
|
||||||
|
/// # Ok::<(), serde_json::Error>(())
|
||||||
|
/// ```
|
||||||
|
pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
|
||||||
|
where
|
||||||
|
D: de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
d.deserialize_option(OptionSecondsTimestampVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OptionSecondsTimestampVisitor;
|
||||||
|
|
||||||
|
impl<'de> de::Visitor<'de> for OptionSecondsTimestampVisitor {
|
||||||
|
type Value = Option<DateTime<Utc>>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a unix timestamp in seconds or none")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a timestamp in seconds since the epoch
|
||||||
|
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
|
||||||
|
where
|
||||||
|
D: de::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
d.deserialize_str(SecondsStringTimestampVisitor).map(Some)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a timestamp in seconds since the epoch
|
||||||
|
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserialize a timestamp in seconds since the epoch
|
||||||
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn serde_from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
V: fmt::Display,
|
||||||
|
T: fmt::Display,
|
||||||
|
{
|
||||||
|
// TODO: Make actual error type
|
||||||
|
match me {
|
||||||
|
LocalResult::None => Err(E::custom("value is not a legal timestamp")),
|
||||||
|
LocalResult::Ambiguous(min, max) => {
|
||||||
|
Err(E::custom("value is an ambiguous timestamp"))
|
||||||
|
}
|
||||||
|
LocalResult::Single(val) => Ok(val),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue