countrs/
types.rs

1//! This module provides `TimeStamp` and `Duration` types which implement
2//! the `Time` and `TimeUnits` traits respectively, for use with `Counter`
3//! and its methods.
4use crate::errors::{TimeOverflow, TimeParserError};
5use crate::times::Time;
6use crate::TimeUnits;
7use chrono::{self, DateTime, Utc};
8use std::fmt::{self, Display, Formatter};
9use std::ops::{Add, Sub};
10use std::str::FromStr;
11
12#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, Clone, Copy)]
13pub struct TimeStamp {
14    time: DateTime<Utc>,
15}
16
17#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
18pub struct Duration {
19    duration: chrono::Duration,
20}
21
22impl Display for TimeStamp {
23    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
24        write!(f, "{}", self.time.to_rfc3339())
25    }
26}
27
28impl FromStr for TimeStamp {
29    type Err = TimeParserError;
30
31    fn from_str(string: &str) -> Result<Self, Self::Err> {
32        Ok(TimeStamp {
33            time: DateTime::parse_from_rfc3339(string)
34                .map_err(|_| TimeParserError)?
35                .into(),
36        })
37    }
38}
39
40impl<T: Into<Duration>> Add<T> for TimeStamp {
41    type Output = TimeStamp;
42
43    fn add(self, duration: T) -> Self::Output {
44        TimeStamp {
45            time: self.time + duration.into().duration,
46        }
47    }
48}
49
50impl<T: Into<Duration>> Sub<T> for TimeStamp {
51    type Output = TimeStamp;
52
53    fn sub(self, duration: T) -> Self::Output {
54        TimeStamp {
55            time: self.time - duration.into().duration,
56        }
57    }
58}
59
60impl Sub<Self> for TimeStamp {
61    type Output = Duration;
62
63    fn sub(self, other: Self) -> Self::Output {
64        Duration {
65            duration: self.time - other.time,
66        }
67    }
68}
69
70impl Time for TimeStamp {
71    type Duration = Duration;
72
73    fn now() -> Self {
74        TimeStamp { time: Utc::now() }
75    }
76
77    fn add(self, duration: Duration) -> Result<TimeStamp, TimeOverflow> {
78        Ok(TimeStamp {
79            time: self
80                .time
81                .checked_add_signed(duration.duration)
82                .ok_or(TimeOverflow)?,
83        })
84    }
85}
86
87impl TimeUnits for Duration {
88    fn seconds(seconds: i64) -> Self {
89        Duration {
90            duration: chrono::Duration::seconds(seconds),
91        }
92    }
93
94    fn num_seconds(&self) -> i64 {
95        self.duration.num_seconds()
96    }
97}
98
99impl From<i64> for Duration {
100    fn from(num: i64) -> Duration {
101        Duration::seconds(num)
102    }
103}