ratelim 0.3.2

Simplistic rate limiter
Documentation
use std::{thread, time::Duration};

use ratelim::{RateLimiter, Timer};

#[test]
fn test_runner() {
    let mut nr_calls = 0;

    let cooldown = Duration::from_millis(50);
    let mut lim = RateLimiter::new(cooldown);
    assert_eq!(lim.cooldown_period(), cooldown);
    // not started, cold
    lim.try_run(|| nr_calls += 1).unwrap(); // hot; 50 ms to cool down
    assert_eq!(nr_calls, 1);
    thread::sleep(Duration::from_millis(10)); // 40 ms to cool down
    let wait = lim.try_run(|| unreachable!()).unwrap_err();
    thread::sleep(wait / 2); // sleep for 20 ms; 20 ms to cool down
    thread::sleep(wait / 4); // sleep for 10 ms; 10 ms to cool down
    let wait = lim.try_run(|| unreachable!()).unwrap_err();
    thread::sleep(wait);
    // cold
    lim.run(|| nr_calls += 1); // hot
    assert_eq!(nr_calls, 2);
    assert!(lim.try_run(|| unreachable!()).is_err());

    let _ = lim.clone();
}

#[test]
fn test_new_hz() {
    let mut lim = RateLimiter::new_hz(20); // 20 Hz => 50 ms cooldown
    assert_eq!(lim.cooldown_period(), Duration::from_millis(50));

    let mut nr_calls = 0;
    lim.run(|| nr_calls += 1); // cold; hot
    assert_eq!(nr_calls, 1);
    assert!(lim.try_run(|| unreachable!()).is_err());
    thread::sleep(Duration::from_millis(50));
    lim.run(|| nr_calls += 1); // hot
    assert_eq!(nr_calls, 2);
}

#[test]
#[should_panic]
fn test_new_hz_zero() {
    RateLimiter::new_hz(0);
}

#[test]
fn test_timer() {
    let _t = Timer::start(|elapsed| eprintln!("slept for {elapsed:?}"));
    thread::sleep(Duration::from_millis(10));

    // Ensure that the API works not only with fn pointers, but also with closures.
    let mut n = 0;
    let _ = Timer::start(|_elapsed| n += 1);
    assert_eq!(n, 1);
}