    -- | Debounce an action, ensuring it doesn't occur more than once for a given
    -- period of time.
    --
    -- This is useful as an optimization, for example to ensure that logs are only
    -- flushed to disk at most once per second.
    --
    -- Example usage:
    --
    -- @
    -- > printString <- 'mkDebounce' 'defaultDebounceSettings'
    --                  { 'debounceAction' = putStrLn "Running action"
    --                  , 'debounceFreq' = 5000000 -- 5 seconds
    --                  , 'debounceEdge' = 'DI.trailingEdge' -- Trigger on the trailing edge
    --                  }
    -- > printString
    -- Running action
    -- > printString
    -- \<Wait five seconds>
    -- Running action
    -- @
    --
    -- See the fast-logger package ("System.Log.FastLogger") for real-world usage.
    --
    -- @since 0.1.2
    module Control.Debounce (
        -- * Creation
        mkDebounce,

        -- * Settings
        DI.DebounceSettings,
        defaultDebounceSettings,

        -- ** Accessors
        DI.debounceFreq,
        DI.debounceAction,
        DI.debounceEdge,
        DI.debounceThreadName,

        -- ** Edge types
        DI.leadingEdge,
        DI.leadingMuteEdge,
        DI.trailingEdge,
        DI.trailingDelayEdge,
    ) where

    import Control.Concurrent (newMVar, threadDelay)
    import qualified Control.Debounce.Internal as DI

    -- | Default value for creating a 'DebounceSettings'.
    --
    -- @since 0.1.2
    defaultDebounceSettings :: DI.DebounceSettings
    defaultDebounceSettings :: DebounceSettings
    defaultDebounceSettings =
        DI.DebounceSettings
            { debounceFreq :: Int
    DI.debounceFreq = Int
    1000000
            , debounceAction :: IO ()
    DI.debounceAction = () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            , debounceEdge :: DebounceEdge
    DI.debounceEdge = DebounceEdge
    DI.leadingEdge
            , debounceThreadName :: String
    DI.debounceThreadName = String
    "Debounce"
            }

    -- | Generate an action which will trigger the debounced action to be performed.
    --
    -- /N.B. The generated action will always immediately return, regardless of the 'debounceFreq',/
    -- /as the debounced action (and the delay\/cooldown) is always performed in a separate thread./
    --
    -- @since 0.1.2
    mkDebounce :: DI.DebounceSettings -> IO (IO ())
    mkDebounce :: DebounceSettings -> IO (IO ())
    mkDebounce DebounceSettings
    settings = do
        baton <- () -> IO (MVar ())
    forall a. a -> IO (MVar a)
    newMVar ()
        DI.mkDebounceInternal baton threadDelay settings