1use rusqlite::types::{FromSql, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
6use rusqlite::Result as RusqliteResult;
7use serde_derive::*;
8use std::fmt;
9use std::time::{Duration, SystemTime, UNIX_EPOCH};
10
11#[derive(
14 Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Default,
15)]
16pub struct Timestamp(pub u64);
17
18impl Timestamp {
19 pub fn now() -> Self {
20 SystemTime::now().into()
21 }
22
23 #[inline]
26 pub fn duration_since(self, other: Timestamp) -> Option<Duration> {
27 SystemTime::from(self).duration_since(other.into()).ok()
29 }
30
31 #[inline]
32 pub fn checked_sub(self, d: Duration) -> Option<Timestamp> {
33 SystemTime::from(self).checked_sub(d).map(Timestamp::from)
34 }
35
36 #[inline]
37 pub fn checked_add(self, d: Duration) -> Option<Timestamp> {
38 SystemTime::from(self).checked_add(d).map(Timestamp::from)
39 }
40
41 pub fn as_millis(self) -> u64 {
42 self.0
43 }
44
45 pub fn as_millis_i64(self) -> i64 {
46 self.0 as i64
47 }
48 pub const EARLIEST: Timestamp = Timestamp(727_747_200_000);
55}
56
57impl From<Timestamp> for u64 {
58 #[inline]
59 fn from(ts: Timestamp) -> Self {
60 ts.0
61 }
62}
63
64impl From<SystemTime> for Timestamp {
65 #[inline]
66 fn from(st: SystemTime) -> Self {
67 let d = st.duration_since(UNIX_EPOCH).unwrap(); Timestamp((d.as_secs()) * 1000 + (u64::from(d.subsec_nanos()) / 1_000_000))
69 }
70}
71
72impl From<Timestamp> for SystemTime {
73 #[inline]
74 fn from(ts: Timestamp) -> Self {
75 UNIX_EPOCH + Duration::from_millis(ts.into())
76 }
77}
78
79impl From<u64> for Timestamp {
80 #[inline]
81 fn from(ts: u64) -> Self {
82 assert!(ts != 0);
83 Timestamp(ts)
84 }
85}
86
87impl fmt::Display for Timestamp {
88 #[inline]
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "{}", self.0)
91 }
92}
93
94impl ToSql for Timestamp {
95 fn to_sql(&self) -> RusqliteResult<ToSqlOutput<'_>> {
96 Ok(ToSqlOutput::from(self.0 as i64)) }
98}
99
100impl FromSql for Timestamp {
101 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
102 value.as_i64().map(|v| Timestamp(v as u64)) }
104}