use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timestamp {
micros: i64,
}
impl Timestamp {
pub fn from_micros(micros: i64) -> Self {
Self { micros }
}
pub fn from_millis(millis: i64) -> Self {
Self {
micros: millis * 1000,
}
}
pub fn from_secs(secs: i64) -> Self {
Self {
micros: secs * 1_000_000,
}
}
pub fn now() -> Self {
let duration = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
Self {
micros: duration.as_micros() as i64,
}
}
pub fn as_micros(&self) -> i64 {
self.micros
}
pub fn as_millis(&self) -> i64 {
self.micros / 1000
}
pub fn as_secs(&self) -> i64 {
self.micros / 1_000_000
}
pub fn value(&self) -> i64 {
self.micros
}
pub fn in_range(&self, start: Timestamp, end: Timestamp) -> bool {
self.micros >= start.micros && self.micros <= end.micros
}
}
impl Default for Timestamp {
fn default() -> Self {
Self::now()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_timestamp_creation() {
let ts = Timestamp::from_secs(1000);
assert_eq!(ts.as_secs(), 1000);
assert_eq!(ts.as_millis(), 1_000_000);
assert_eq!(ts.as_micros(), 1_000_000_000);
}
#[test]
fn test_timestamp_ordering() {
let ts1 = Timestamp::from_secs(100);
let ts2 = Timestamp::from_secs(200);
assert!(ts1 < ts2);
assert!(ts2 > ts1);
}
#[test]
fn test_timestamp_range() {
let start = Timestamp::from_secs(100);
let end = Timestamp::from_secs(200);
let middle = Timestamp::from_secs(150);
let before = Timestamp::from_secs(50);
assert!(middle.in_range(start, end));
assert!(!before.in_range(start, end));
}
#[test]
fn test_timestamp_now() {
let ts = Timestamp::now();
assert!(ts.as_secs() > 0);
}
}