From f12a839d6e6bdd29a86ac52d5de836519a41aaf0 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 26 Oct 2026 05:38:41 +0100 Subject: wrap unix timestamps in newtype --- src/clock.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'src/clock.rs') diff --git a/src/clock.rs b/src/clock.rs index dafd44b..7613930 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -7,6 +7,46 @@ //! isn't affected. use std::sync::atomic::{AtomicI64, Ordering}; +use std::time::Duration; + +use serde::{Deserialize, Serialize}; + +/// A point in time as Unix milliseconds, as stored in the document and reported: not a +/// duration (those are `Duration`, or plain milliseconds named `…_ms`). Comparable +/// across nodes as far as their clocks agree; for elapsed time within a node use +/// tokio's `Instant`. +#[derive( + Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, +)] +#[serde(transparent)] +pub(crate) struct UnixMillis(pub(crate) u64); + +impl UnixMillis { + pub(crate) fn as_u64(self) -> u64 { + self.0 + } + + /// `ms` milliseconds later (saturating). + pub(crate) fn plus_ms(self, ms: u64) -> Self { + Self(self.0.saturating_add(ms)) + } + + /// `duration` later (saturating, to the millisecond). + pub(crate) fn plus(self, duration: Duration) -> Self { + self.plus_ms(u64::try_from(duration.as_millis()).unwrap_or(u64::MAX)) + } + + /// Milliseconds from `earlier` to this; 0 if `earlier` is later. + pub(crate) fn ms_since(self, earlier: Self) -> u64 { + self.0.saturating_sub(earlier.0) + } +} + +impl std::fmt::Display for UnixMillis { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} /// The node's wall clock: the system clock plus an offset (zero outside tests). #[derive(Debug, Default)] @@ -15,10 +55,10 @@ pub(crate) struct Clock { } impl Clock { - /// Now, in Unix milliseconds. - pub(crate) fn now_millis(&self) -> u64 { + /// Now. + pub(crate) fn now_millis(&self) -> UnixMillis { let offset = self.offset_ms.load(Ordering::Relaxed); - system_millis().saturating_add_signed(offset) + UnixMillis(system_millis().saturating_add_signed(offset)) } /// Puts this clock `offset_ms` ahead of the system clock (behind if negative). @@ -46,7 +86,7 @@ mod tests { let before = clock.now_millis(); clock.set_offset_ms(3_600_000); let ahead = clock.now_millis(); - assert!(ahead >= before + 3_600_000); + assert!(ahead >= before.plus_ms(3_600_000)); clock.set_offset_ms(-3_600_000); assert!(clock.now_millis() < before); } -- cgit v1.3.1