fire_postgres/time/
timeout.rs1use crate::table::column::{ColumnData, ColumnKind, ColumnType, FromDataError};
2use std::time::{Duration, SystemTime};
3
4use serde::de::{Deserializer, Error};
5use serde::ser::Serializer;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone)]
9pub struct Timeout {
10 inner: SystemTime,
11}
12
13impl Timeout {
14 pub fn new(dur: Duration) -> Self {
15 Self {
16 inner: SystemTime::now() + dur,
17 }
18 }
19
20 pub fn now() -> Self {
21 Self {
22 inner: SystemTime::now(),
23 }
24 }
25
26 pub fn has_elapsed(&self) -> bool {
27 SystemTime::now() > self.inner
28 }
29
30 pub fn remaining(&self) -> Option<Duration> {
32 self.inner.duration_since(SystemTime::now()).ok()
33 }
34
35 pub fn as_secs(&self) -> u64 {
37 self.inner
38 .duration_since(SystemTime::UNIX_EPOCH)
39 .expect("Welcome to the past!")
40 .as_secs()
41 }
42
43 pub fn from_secs(s: u64) -> Option<Self> {
44 SystemTime::UNIX_EPOCH
45 .checked_add(Duration::from_secs(s))
46 .map(|c| Timeout { inner: c })
47 }
48}
49
50impl Serialize for Timeout {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: Serializer,
54 {
55 serializer.serialize_u64(self.as_secs())
56 }
57}
58
59impl<'de> Deserialize<'de> for Timeout {
60 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
61 where
62 D: Deserializer<'de>,
63 {
64 let num: u64 = Deserialize::deserialize(deserializer)?;
65 Self::from_secs(num).ok_or(D::Error::custom("timeout to big"))
66 }
67}
68
69impl ColumnType for Timeout {
70 fn column_kind() -> ColumnKind {
71 ColumnKind::I64
72 }
73
74 fn to_data(&self) -> ColumnData<'static> {
75 ColumnData::I64(self.as_secs().try_into().expect("timeout to large"))
76 }
77
78 fn from_data(data: ColumnData) -> Result<Self, FromDataError> {
79 match data {
80 ColumnData::I64(u) => match u64::try_from(u) {
81 Ok(u) => Self::from_secs(u)
82 .ok_or(FromDataError::Custom("timeout to large")),
83 Err(e) => Err(FromDataError::CustomString(e.to_string())),
84 },
85 _ => Err(FromDataError::ExpectedType("expected i64 for u64")),
86 }
87 }
88}