blocking-permit 1.3.3

Permits and a thread pool for blocking operations
Documentation
/// Attempt to dispatch a blocking operation, or otherwise obtain a permit and
/// run on thread, returning the result of the closure.
///
/// This helper macro is intended for use in the context of an `async` block or
/// function. It first attempts to dispatch the closure via
/// [`dispatch_rx()`](crate::dispatch_rx) and await. If a dispatch pool is not
/// registered on the current thread, it instead obtains a permit via
/// [`blocking_permit_future()`](crate::blocking_permit_future) and awaits.  If
/// the _tokio-threaded_ feature is enabled, it will then run the closure via
/// [`BlockingPermit::run()`](crate::BlockingPermit::run). Otherwise it will
/// run the closure directly.
///
/// ## Usage
///
/// The closure should return a `Result<T, E>` where `From<Canceled>` is
/// implemented for type E. The return type of the closure may be annotated as
/// necessary. The closure may also be a `move` closure.
///
/// ```rust no_compile no_run
/// async {
///     dispatch_or_permit!(&semaphore, move || { /*.. blocking code..*/ });
/// }
/// ```
#[macro_export] macro_rules! dispatch_or_permit {
    ($semaphore:expr, $closure:expr) => {{
        match $crate::dispatch_rx($closure) {
            $crate::DispatchRx::Dispatch(disp) => {
                disp .await?
            }
            $crate::DispatchRx::NotRegistered(cl) => {
                let permit = $crate::blocking_permit_future($semaphore) .await?;
                permit.run(cl)
            }
        }
    }};
}