scoped_sleep/
scoped_sleep.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/// RAII sleep
pub struct ScopedSleep {
    target_time: std::time::Instant,
}

impl ScopedSleep {
    /// Create sleep
    ///
    /// # Example
    /// ```
    /// let now = std::time::Instant::now();
    /// {
    ///     // Do not use `let _ = ..` here because it immediately drops ScopedSleep.
    ///     let _guard = scoped_sleep::ScopedSleep::new(std::time::Duration::from_millis(100));
    ///     // not sleep yet
    ///     assert!(now.elapsed() < std::time::Duration::from_millis(20));
    /// }
    /// // slept
    /// assert!(now.elapsed() > std::time::Duration::from_millis(20));
    /// ```
    pub fn new(sleep_duration: std::time::Duration) -> Self {
        ScopedSleep {
            target_time: std::time::Instant::now() + sleep_duration,
        }
    }

    /// Create sleep from float secs value
    ///
    /// # Example
    /// ```
    /// let now = std::time::Instant::now();
    /// {
    ///     // Do not use `let _ = ..` here because it immediately drops ScopedSleep.
    ///     let _guard = scoped_sleep::ScopedSleep::from_secs(0.1);
    ///     // not sleep yet
    ///     assert!(now.elapsed() < std::time::Duration::from_millis(10));
    /// }
    /// // slept
    /// assert!(now.elapsed() > std::time::Duration::from_millis(10));
    /// ```
    pub fn from_secs(sleep_duration_sec: f64) -> Self {
        Self::new(std::time::Duration::from_secs_f64(sleep_duration_sec))
    }
}

impl Drop for ScopedSleep {
    fn drop(&mut self) {
        let now = std::time::Instant::now();
        if now < self.target_time {
            std::thread::sleep(self.target_time - now);
        }
    }
}