use core::time::Duration;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct WatchOptions {
debounce: Duration,
ceiling: Option<Duration>,
grace: Option<Duration>,
}
impl WatchOptions {
#[must_use]
pub const fn new(debounce: Duration) -> Self {
Self {
debounce,
ceiling: None,
grace: None,
}
}
#[must_use]
pub const fn ceiling(mut self, ceiling: Duration) -> Self {
self.ceiling = Some(ceiling);
self
}
#[must_use]
pub const fn atomic_save_grace(mut self, grace: Duration) -> Self {
self.grace = Some(grace);
self
}
#[must_use]
pub const fn debounce_of(&self) -> Duration {
self.debounce
}
#[must_use]
pub(crate) fn ceiling_of(&self) -> Duration {
self.ceiling
.unwrap_or_else(|| self.debounce.saturating_mul(4))
}
#[must_use]
pub(crate) fn grace_of(&self) -> Duration {
self.grace
.unwrap_or_else(super::debounce::atomic_save_grace)
}
}
impl From<Duration> for WatchOptions {
fn from(debounce: Duration) -> Self {
Self::new(debounce)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_bare_duration_is_the_one_argument_form() {
let options: WatchOptions = Duration::from_millis(100).into();
assert_eq!(options.debounce_of(), Duration::from_millis(100));
}
#[test]
fn the_ceiling_defaults_to_four_debounces() {
let options = WatchOptions::new(Duration::from_millis(100));
assert_eq!(options.ceiling_of(), Duration::from_millis(400));
}
#[test]
fn a_named_ceiling_wins() {
let options = WatchOptions::new(Duration::from_millis(100)).ceiling(Duration::from_secs(2));
assert_eq!(options.ceiling_of(), Duration::from_secs(2));
}
#[test]
fn the_grace_falls_back_to_the_process_wide_value() {
let options = WatchOptions::new(Duration::from_millis(100));
assert_eq!(
options.grace_of(),
super::super::debounce::atomic_save_grace()
);
let named = options.atomic_save_grace(Duration::from_millis(70));
assert_eq!(named.grace_of(), Duration::from_millis(70));
}
#[test]
fn a_ceiling_under_the_debounce_is_taken_at_its_word() {
let options = WatchOptions::new(Duration::from_secs(1)).ceiling(Duration::from_millis(10));
assert_eq!(options.ceiling_of(), Duration::from_millis(10));
}
}