async-utils 0.1.1

nothing to see here yet :)
Documentation
use ::std::ops::{Deref, DerefMut};

pub trait MutexFamily {
    type Mutex<T: Send + 'static>: Mutex<T>;

    fn new<T: Send + 'static>(val: T) -> Self::Mutex<T>;
}

pub trait Mutex<T>: Send + Sync + 'static {
    type Guard<'a>: Guard<T>
    where
        Self: 'a,
        T: 'a;

    fn lock(&self) -> Self::Guard<'_>;
}

pub trait Guard<T>: Deref<Target = T> + DerefMut {}

pub type MutexGuardType<'a, M, T> = <<M as MutexFamily>::Mutex<T> as Mutex<T>>::Guard<'a>;

#[cfg(feature = "parking_lot")]
pub use self::parking_lot::ParkingLotMutex;
pub use self::std::StdMutex;

mod std {
    use super::{Guard, Mutex, MutexFamily};

    pub struct StdMutex;

    impl MutexFamily for StdMutex {
        type Mutex<T: Send + 'static> = std::sync::Mutex<T>;

        #[inline]
        fn new<T: Send + 'static>(val: T) -> Self::Mutex<T> {
            std::sync::Mutex::new(val)
        }
    }

    impl<T: Send + 'static> Mutex<T> for std::sync::Mutex<T> {
        type Guard<'a> = std::sync::MutexGuard<'a, T>
        where
            T: 'a;

        #[inline]
        fn lock(&self) -> Self::Guard<'_> {
            self.lock().unwrap()
        }
    }

    impl<'a, T: 'a> Guard<T> for std::sync::MutexGuard<'a, T> {}
}

#[cfg(feature = "parking_lot")]
mod parking_lot {
    use super::{Guard, Mutex, MutexFamily};

    pub struct ParkingLotMutex;

    impl MutexFamily for ParkingLotMutex {
        type Mutex<T: Send + 'static> = parking_lot::Mutex<T>;

        #[inline]
        fn new<T: Send + 'static>(val: T) -> Self::Mutex<T> {
            parking_lot::Mutex::new(val)
        }
    }

    impl<T: Send + 'static> Mutex<T> for parking_lot::Mutex<T> {
        type Guard<'a> = parking_lot::MutexGuard<'a, T>
        where
            T: 'a;

        #[inline]
        fn lock(&self) -> Self::Guard<'_> {
            self.lock()
        }
    }

    impl<'a, T: 'a> Guard<T> for parking_lot::MutexGuard<'a, T> {}
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;

    #[cfg(feature = "parking_lot")]
    use crate::sync::mutex::ParkingLotMutex;
    use crate::sync::mutex::{Mutex, MutexFamily, StdMutex};

    struct Data {
        a: usize,
    }

    #[test]
    fn mutex() {
        fn generic<M: MutexFamily>() {
            let data = Arc::new(M::new(Data { a: 0 }));

            {
                let data = Arc::clone(&data);
                std::thread::spawn(move || {
                    let mut guard = data.lock();
                    guard.a += 1;
                })
                .join()
                .unwrap();
            }

            let mut guard = data.lock();
            guard.a += 1;

            assert_eq!(guard.a, 2);
        }

        generic::<StdMutex>();

        #[cfg(feature = "parking_lot")]
        generic::<ParkingLotMutex>();
    }
}