1pub trait Clock {
2 fn timestamp(&self) -> String;
3}
4
5pub struct SystemClock;
6
7impl Clock for SystemClock {
8 fn timestamp(&self) -> String {
9 use time::format_description::FormatItem;
10 use time::macros::format_description;
11 const FMT: &[FormatItem] =
12 format_description!("[year]-[month]-[day]T[hour]-[minute]-[second]Z");
13 time::OffsetDateTime::now_utc()
14 .format(&FMT)
15 .expect("format utc timestamp")
16 }
17}
18
19pub struct FixedClock(pub String);
20
21impl Clock for FixedClock {
22 fn timestamp(&self) -> String {
23 self.0.clone()
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 #[test]
31 fn fixed_clock_returns_its_value() {
32 assert_eq!(
33 FixedClock("2026-01-02T03-04-05Z".into()).timestamp(),
34 "2026-01-02T03-04-05Z"
35 );
36 }
37 #[test]
38 fn system_clock_is_safe_and_zulu() {
39 let t = SystemClock.timestamp();
40 assert!(t.ends_with('Z'));
41 assert!(
42 !t.contains(':'),
43 "colons are avoided for key/filename safety"
44 );
45 }
46}