Skip to main content

solti_model/domain/
timeout.rs

1//! # Per-attempt timeout.
2//!
3//! [`Timeout`] is a validated wrapper over milliseconds, used in [`TaskSpec`](crate::TaskSpec).
4
5use std::fmt;
6
7use serde::{Deserialize, Serialize};
8
9/// Timeout value in milliseconds.
10///
11/// ```
12/// use solti_model::Timeout;
13///
14/// let timeout = Timeout::new(5_000);
15/// assert_eq!(timeout.as_millis(), 5_000);
16///
17/// let timeout: Timeout = 10_000.into();
18/// assert_eq!(format!("{timeout}"), "10000ms");
19/// ```
20#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
21#[serde(transparent)]
22pub struct Timeout(u64);
23
24impl Timeout {
25    /// Create a new timeout value.
26    pub const fn new(ms: u64) -> Self {
27        Self(ms)
28    }
29
30    /// Get the timeout in milliseconds.
31    pub const fn as_millis(&self) -> u64 {
32        self.0
33    }
34}
35
36impl From<u64> for Timeout {
37    #[inline]
38    fn from(ms: u64) -> Self {
39        Self(ms)
40    }
41}
42
43impl From<Timeout> for u64 {
44    #[inline]
45    fn from(t: Timeout) -> Self {
46        t.0
47    }
48}
49
50impl fmt::Display for Timeout {
51    #[inline]
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        write!(f, "{}ms", self.0)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::Timeout;
60
61    #[test]
62    fn new_and_as_millis() {
63        let t = Timeout::new(3_000);
64        assert_eq!(t.as_millis(), 3_000);
65    }
66
67    #[test]
68    fn from_u64_and_into() {
69        let t: Timeout = 5_000.into();
70        let v: u64 = t.into();
71        assert_eq!(v, 5_000);
72    }
73
74    #[test]
75    fn display() {
76        let t = Timeout::new(1_500);
77        assert_eq!(format!("{t}"), "1500ms");
78    }
79
80    #[test]
81    fn ordering() {
82        let a = Timeout::new(100);
83        let b = Timeout::new(200);
84        assert!(a < b);
85    }
86
87    #[test]
88    fn serde_transparent() {
89        let t = Timeout::new(5_000);
90        let json = serde_json::to_string(&t).unwrap();
91        assert_eq!(json, "5000");
92
93        let back: Timeout = serde_json::from_str(&json).unwrap();
94        assert_eq!(back, t);
95    }
96}