use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
pub trait TimestampSource: Send + Sync {
fn now_timestamp_seconds(&self) -> i64;
}
impl<TimestampFn> TimestampSource for TimestampFn
where
TimestampFn: Fn() -> i64 + Send + Sync,
{
fn now_timestamp_seconds(&self) -> i64 {
self()
}
}
pub(crate) fn system_timestamp_source() -> Arc<dyn TimestampSource> {
Arc::new(system_timestamp_seconds)
}
fn system_timestamp_seconds() -> i64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.ok()
.and_then(|duration| i64::try_from(duration.as_secs()).ok())
.unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn closure_timestamp_source_returns_injected_value() {
let timestamp_source = || 123;
let timestamp = timestamp_source.now_timestamp_seconds();
assert_eq!(timestamp, 123);
}
#[test]
fn system_timestamp_source_returns_a_post_epoch_value() {
let timestamp_source = system_timestamp_source();
let timestamp = timestamp_source.now_timestamp_seconds();
assert!(timestamp > 0);
}
}