potential 3.0.1

PubSub lib with sync and async API
Documentation
use std::{
    ops::{Deref, Not as _},
    sync::atomic::{AtomicBool, Ordering},
    thread::park_timeout,
    time::Duration,
};

pub struct Lock<T: Deref<Target = AtomicBool>>(T);
impl<T> Lock<T>
where
    T: Deref<Target = AtomicBool>,
{
    pub fn try_get(locked: T) -> Option<Self> {
        locked
            .deref()
            .swap(true, Ordering::AcqRel)
            .not()
            .then(|| Lock(locked))
    }
    pub fn get(locked: T, timeout: Duration) -> Self {
        let steps = 32;
        for n in 0..steps {
            if !locked.deref().swap(true, Ordering::AcqRel) {
                return Lock(locked);
            }
            let timeout = timeout.as_secs_f32() * 1024.0 * 1024.0 * 1024.0;
            let base = timeout.powf(1.0 / steps as f32);
            let duration = Duration::from_nanos(base.powi(n) as u64);
            park_timeout(duration);
        }
        unreachable!("Failed to get a lock");
    }
}
impl<T: Deref<Target = AtomicBool>> Drop for Lock<T> {
    fn drop(&mut self) {
        self.0.deref().store(false, Ordering::Release);
    }
}

#[test]
#[should_panic]
fn times_out() {
    let busy = true.into();
    Lock::get(&busy, Duration::from_millis(10));
}

#[test]
fn locks_unlocks() {
    let busy = AtomicBool::new(false);
    let lock = Lock::get(&busy, Duration::from_millis(10));
    assert!(busy.load(Ordering::Relaxed));
    drop(lock);
    assert!(!busy.load(Ordering::Relaxed));
}