sofie_core/clock/
shifted.rs1use jiff::{SignedDuration, Timestamp};
2
3use super::{Clock, Source};
4use crate::Instant;
5
6impl Clock {
7 #[must_use]
8 pub fn starting_at(start: Instant) -> Self {
9 Self {
10 source: Source::Shifted(start.timestamp().duration_since(Timestamp::now())),
11 }
12 }
13
14 #[must_use]
16 pub fn shifted(&self, seconds: i64) -> Self {
17 let offset = self.now().timestamp().duration_since(Timestamp::now());
18 Self {
19 source: Source::Shifted(offset.saturating_add(SignedDuration::from_secs(seconds))),
20 }
21 }
22}
23
24pub(super) fn now(offset: SignedDuration) -> Instant {
26 Instant::from(
27 Timestamp::now()
28 .saturating_add(offset)
29 .unwrap_or(Timestamp::MAX),
30 )
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn a_shifted_clock_starts_at_its_moment_and_runs_on() {
39 let start = Instant::parse("2027-01-01T09:00").unwrap();
40
41 let clock = Clock::starting_at(start);
42
43 let now = clock.now().timestamp();
44 assert!(now >= start.timestamp(), "{now}");
45 assert!(now.duration_since(start.timestamp()) < SignedDuration::from_secs(5));
46 }
47
48 #[test]
49 fn a_shifted_clock_runs_the_given_seconds_ahead_of_its_source() {
50 let start = Instant::parse("2027-01-01T09:00").unwrap();
51
52 let clock = Clock::starting_at(start).shifted(-3600);
53
54 let behind = start.timestamp().duration_since(clock.now().timestamp());
55 assert!(behind > SignedDuration::from_mins(59), "{behind}");
56 assert!(behind <= SignedDuration::from_mins(60), "{behind}");
57 }
58}