appletheia_application/outbox/
outbox_published_at.rs1use std::{fmt, fmt::Display};
2
3use chrono::{DateTime, Utc};
4
5#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
6pub struct OutboxPublishedAt(DateTime<Utc>);
7
8impl OutboxPublishedAt {
9 pub fn now() -> Self {
10 Self(Utc::now())
11 }
12
13 pub fn value(&self) -> DateTime<Utc> {
14 self.0
15 }
16}
17
18impl Default for OutboxPublishedAt {
19 fn default() -> Self {
20 Self::now()
21 }
22}
23
24impl From<DateTime<Utc>> for OutboxPublishedAt {
25 fn from(value: DateTime<Utc>) -> Self {
26 Self(value)
27 }
28}
29
30impl From<OutboxPublishedAt> for DateTime<Utc> {
31 fn from(value: OutboxPublishedAt) -> Self {
32 value.0
33 }
34}
35
36impl Display for OutboxPublishedAt {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "{}", self.value())
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use chrono::TimeZone;
46
47 #[test]
48 fn new_produces_timestamp_close_to_now() {
49 let before = Utc::now();
50 let published_at = OutboxPublishedAt::now();
51 let after = Utc::now();
52
53 let published_at = published_at.value();
54 assert!(
55 published_at >= before,
56 "expected {published_at} to be after {before}"
57 );
58 assert!(
59 published_at <= after,
60 "expected {published_at} to be before {after}"
61 );
62 }
63
64 #[test]
65 fn value_returns_inner_datetime() {
66 let timestamp = Utc.with_ymd_and_hms(2024, 1, 2, 3, 4, 5).unwrap();
67 let published_at = OutboxPublishedAt::from(timestamp);
68
69 assert_eq!(published_at.value(), timestamp);
70 }
71
72 #[test]
73 fn conversions_round_trip() {
74 let timestamp = Utc.with_ymd_and_hms(2022, 6, 7, 8, 9, 10).unwrap();
75 let published_at: OutboxPublishedAt = timestamp.into();
76 let back_into_datetime: DateTime<Utc> = published_at.into();
77
78 assert_eq!(back_into_datetime, timestamp);
79 }
80
81 #[test]
82 fn display_matches_inner_datetime() {
83 let timestamp = Utc.with_ymd_and_hms(2030, 12, 31, 23, 59, 59).unwrap();
84 let published_at = OutboxPublishedAt::from(timestamp);
85
86 assert_eq!(published_at.to_string(), timestamp.to_string());
87 }
88}