//! Wait policy for a debounced function.

use std::sync::Arc;
use std::time::Duration;

/// How long a window stays open.
///
/// A fixed duration uses the same wait for every call. A dynamic policy calls a
/// closure on every call to read the current wait, so the window length can
/// change at runtime. The closure runs once per call, never cached.
#[derive(Clone)]
pub(crate) enum Wait {
    /// Same wait for every call.
    Fixed(Duration),
    /// Wait read fresh on each call from a closure.
    Dynamic(Arc<dyn Fn() -> Duration + Send + Sync>),
}

impl Wait {
    /// Read the current wait. Calls the closure for a dynamic policy.
    pub(crate) fn get(&self) -> Duration {
        match self {
            Wait::Fixed(d) => *d,
            Wait::Dynamic(f) => f(),
        }
    }
}

impl std::fmt::Debug for Wait {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Wait::Fixed(d) => f.debug_tuple("Fixed").field(d).finish(),
            Wait::Dynamic(_) => f.debug_tuple("Dynamic").field(&"<fn>").finish(),
        }
    }
}
