1use quanta::Clock;
7use serde::{Deserialize, Serialize};
8use std::fmt::{self, Display};
9use std::time::Duration;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13pub enum LogLevel {
14 Trace,
16 Debug,
18 Info,
20 Warn,
22 Error,
24 Fatal,
26}
27
28impl Display for LogLevel {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Trace => write!(f, "TRACE"),
32 Self::Debug => write!(f, "DEBUG"),
33 Self::Info => write!(f, "INFO"),
34 Self::Warn => write!(f, "WARN"),
35 Self::Error => write!(f, "ERROR"),
36 Self::Fatal => write!(f, "FATAL"),
37 }
38 }
39}
40
41pub type Result<T> = std::result::Result<T, anyhow::Error>;
43
44#[inline]
46#[must_use]
47pub fn current_time_ns() -> u64 {
48 let clock = Clock::new();
50 clock.raw()
51}
52
53#[inline]
55#[must_use]
56pub const fn nanoseconds_to_milliseconds(nanoseconds: u64) -> u64 {
57 nanoseconds / 1_000_000
58}
59
60#[inline]
62#[must_use]
63pub const fn milliseconds_to_nanoseconds(milliseconds: u64) -> u64 {
64 milliseconds * 1_000_000
65}
66
67#[inline]
69#[must_use]
70pub fn is_stale(timestamp_ns: u64, max_age: Duration) -> bool {
71 let clock = Clock::new();
72 let now = clock.raw();
73 let age_ns = now.saturating_sub(timestamp_ns);
74
75 age_ns > u64::try_from(max_age.as_nanos()).unwrap_or(u64::MAX)
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_time_conversions() {
84 assert_eq!(nanoseconds_to_milliseconds(0), 0);
86 assert_eq!(nanoseconds_to_milliseconds(1_000_000), 1);
87 assert_eq!(nanoseconds_to_milliseconds(1_500_000), 1); assert_eq!(nanoseconds_to_milliseconds(1_000_000_000), 1_000);
89
90 assert_eq!(milliseconds_to_nanoseconds(0), 0);
92 assert_eq!(milliseconds_to_nanoseconds(1), 1_000_000);
93 assert_eq!(milliseconds_to_nanoseconds(1_000), 1_000_000_000);
94 }
95
96 #[test]
97 fn test_time_conversions_const_context() {
98 const ZERO_NANOS: u64 = 0;
100 const MILLION_NANOS: u64 = 1_000_000;
101 const BILLION_NANOS: u64 = 1_000_000_000;
102
103 const ZERO_MILLIS: u64 = nanoseconds_to_milliseconds(ZERO_NANOS);
104 const ONE_MILLI: u64 = nanoseconds_to_milliseconds(MILLION_NANOS);
105 const THOUSAND_MILLIS: u64 = nanoseconds_to_milliseconds(BILLION_NANOS);
106
107 assert_eq!(ZERO_MILLIS, 0);
108 assert_eq!(ONE_MILLI, 1);
109 assert_eq!(THOUSAND_MILLIS, 1_000);
110
111 const BACK_TO_NANOS: u64 = milliseconds_to_nanoseconds(ONE_MILLI);
112 const BACK_TO_BILLION: u64 = milliseconds_to_nanoseconds(THOUSAND_MILLIS);
113
114 assert_eq!(BACK_TO_NANOS, 1_000_000);
115 assert_eq!(BACK_TO_BILLION, 1_000_000_000);
116 }
117}