square_api_client/models/
date_time.rs

1//! Model struct for DateTime type.
2
3use std::fmt::{Debug, Display};
4
5use chrono::Utc;
6use log::error;
7use serde::{Deserialize, Serialize};
8
9use super::errors::ApiError;
10
11/// Represents a Timestamp or DateTime.
12///
13/// Handles Serialization and Deserialization and conversion between Square standard
14/// RFC3339 String and Unix Timestamp i64.
15///
16/// Uses chrono library under the hood.
17#[derive(Clone, Eq, PartialEq)]
18pub struct DateTime {
19    inner: chrono::DateTime<Utc>,
20}
21
22impl DateTime {
23    /// Generates a new `DateTime` representing the present time.
24    ///
25    /// Alias for `DateTime::now()`
26    pub fn new() -> Self {
27        Self::now()
28    }
29
30    /// Generates a new `DateTime` representing the present time.
31    ///
32    /// Alias for `DateTime::new()`
33    pub fn now() -> Self {
34        Self {
35            inner: chrono::offset::Utc::now(),
36        }
37    }
38}
39
40impl Debug for DateTime {
41    /// Unwraps the inner DateTime for Debug.
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        std::fmt::Debug::fmt(&self.inner, f)
44    }
45}
46
47impl Default for DateTime {
48    /// Default `DateTime` is the present/current time.
49    ///
50    /// Alias for `DateTime::now()`
51    fn default() -> Self {
52        Self::now()
53    }
54}
55
56impl<'de> Deserialize<'de> for DateTime {
57    /// Attempts to generate a `DateTime` from its serialized version.
58    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59    where
60        D: serde::Deserializer<'de>,
61    {
62        Ok(Self {
63            inner: chrono::DateTime::deserialize(deserializer)?,
64        })
65    }
66}
67
68impl Display for DateTime {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        std::fmt::Display::fmt(&self.inner, f)
71    }
72}
73
74impl From<&chrono::DateTime<Utc>> for DateTime {
75    /// Converts a `chrono::DateTime<Utc>` reference into a `DateTime`.
76    fn from(dt: &chrono::DateTime<Utc>) -> Self {
77        Self {
78            inner: dt.to_owned(),
79        }
80    }
81}
82
83impl From<i64> for DateTime {
84    /// Converts a Unix timestamp into a `DateTime`.
85    fn from(timestamp: i64) -> Self {
86        Self::from(&chrono::DateTime::<Utc>::from_utc(
87            chrono::NaiveDateTime::from_timestamp(timestamp, 0),
88            Utc,
89        ))
90    }
91}
92
93impl Serialize for DateTime {
94    /// Unwraps the inner DateTime for Serialization.
95    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
96    where
97        S: serde::Serializer,
98    {
99        self.inner.serialize(serializer)
100    }
101}
102
103impl TryFrom<&str> for DateTime {
104    type Error = ApiError;
105
106    /// Attempts to generate a `DateTime` from RFC3339 formatted String slice.
107    ///
108    /// Returns an API Error if the input String slice cannot be parsed.
109    fn try_from(rfc3339: &str) -> Result<Self, Self::Error> {
110        let inner = chrono::DateTime::parse_from_rfc3339(rfc3339).map_err(|e| {
111            let msg = format!("Error parsing RFC3339 DateTime string: {}: {}", rfc3339, e);
112            error!("{}", &msg);
113            Self::Error::new(&msg)
114        })?;
115        let inner = inner.with_timezone(&chrono::offset::Utc);
116        Ok(Self { inner })
117    }
118}