use crate::sql::duration::Duration; use crate::sql::strand::Strand; use crate::syn; use chrono::{DateTime, SecondsFormat, Utc}; use revision::revisioned; use serde::{Deserialize, Serialize}; use std::fmt::{self, Display, Formatter}; use std::ops; use std::ops::Deref; use std::str; use std::str::FromStr; use super::escape::quote_str; pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Datetime"; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, Hash)] #[serde(rename = "$surrealdb::private::sql::Datetime")] #[revisioned(revision = 1)] pub struct Datetime(pub DateTime); impl Default for Datetime { fn default() -> Self { Self(Utc::now()) } } impl From> for Datetime { fn from(v: DateTime) -> Self { Self(v) } } impl From for DateTime { fn from(x: Datetime) -> Self { x.0 } } impl FromStr for Datetime { type Err = (); fn from_str(s: &str) -> Result { Self::try_from(s) } } impl TryFrom for Datetime { type Error = (); fn try_from(v: String) -> Result { Self::try_from(v.as_str()) } } impl TryFrom for Datetime { type Error = (); fn try_from(v: Strand) -> Result { Self::try_from(v.as_str()) } } impl TryFrom<&str> for Datetime { type Error = (); fn try_from(v: &str) -> Result { match syn::datetime_raw(v) { Ok(v) => Ok(v), _ => Err(()), } } } impl Deref for Datetime { type Target = DateTime; fn deref(&self) -> &Self::Target { &self.0 } } impl Datetime { /// Convert the Datetime to a raw String pub fn to_raw(&self) -> String { self.0.to_rfc3339_opts(SecondsFormat::AutoSi, true) } } impl Display for Datetime { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Display::fmt("e_str(&self.to_raw()), f) } } impl ops::Sub for Datetime { type Output = Duration; fn sub(self, other: Self) -> Duration { match (self.0 - other.0).to_std() { Ok(d) => Duration::from(d), Err(_) => Duration::default(), } } }