From 25e548352502deab508f3843431ca34f288f895e Mon Sep 17 00:00:00 2001 From: Juliette Cordor Date: Wed, 4 Dec 2024 12:40:14 +1100 Subject: [PATCH] added new map trait that replaces LockMap --- Cargo.toml | 1 + src/traits/lock.rs | 5 ++++ src/traits/map.rs | 41 ++++++++++++++++++++++++++++++ src/traits/map/mutex.rs | 56 +++++++++++++++++++++++++++++++++++++++++ src/traits/mod.rs | 2 ++ 5 files changed, 105 insertions(+) create mode 100644 src/traits/map.rs create mode 100644 src/traits/map/mutex.rs diff --git a/Cargo.toml b/Cargo.toml index c221491..5a43aa3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = ["quork-proc"] [dependencies] cfg-if = "1.0" lock_api = { version = "0.4", optional = true } +parking_lot = { version = "0.12", optional = true } quork-proc = { version = "0.3", path = "quork-proc", optional = true } spin = { version = "0.9", optional = true } thiserror = { version = "1.0" } diff --git a/src/traits/lock.rs b/src/traits/lock.rs index f094838..24f4aff 100644 --- a/src/traits/lock.rs +++ b/src/traits/lock.rs @@ -1,3 +1,8 @@ +#![deprecated( + since = "0.8.0", + note = "Use the `map::Map` trait instead. This trait will be removed in the future." +)] + //! Map a Mutex Lock //! //! Can theoretically be anything but designed primarily for Mutex Locks diff --git a/src/traits/map.rs b/src/traits/map.rs new file mode 100644 index 0000000..8927de8 --- /dev/null +++ b/src/traits/map.rs @@ -0,0 +1,41 @@ +//! Provides a generalized map function +//! +//! This is primarily designed for mapping Mutex types, but can realistically be used for anything in future. + +mod mutex; + +#[allow(clippy::module_name_repetitions)] +/// Map a mutex lock +pub trait Map<'a, 'g, T: ?Sized, G: 'g> { + /// Maps a value of T to a value of U + fn map(&'a self, f: F) -> U + where + F: FnOnce(G) -> U + 'g, + 'a: 'g; +} + +#[allow(clippy::module_name_repetitions)] +/// Attempts to map a mutex lock +pub trait TryMap<'a, 'g, T: ?Sized, G: 'g, E = G> { + /// Maps a value of T to a value of U + /// + /// # Errors + /// - Locking the mutex failed + fn try_map(&'a self, f: F) -> Result + where + F: FnOnce(G) -> U + 'g, + 'a: 'g; +} + +// impl<'a, 'g, T: ?Sized, G: 'g, S> TryMap<'a, 'g, T, G> for S +// where +// S: Map<'a, 'g, T, G>, +// { +// fn try_map(&'a self, f: F) -> Result +// where +// F: FnOnce(G) -> U + 'g, +// 'a: 'g, +// { +// Ok(self.map(f)) +// } +// } diff --git a/src/traits/map/mutex.rs b/src/traits/map/mutex.rs new file mode 100644 index 0000000..98a012f --- /dev/null +++ b/src/traits/map/mutex.rs @@ -0,0 +1,56 @@ +#[cfg(feature = "parking_lot")] +impl<'a, 'g, T> super::Map<'a, 'g, T, parking_lot::MutexGuard<'g, T>> for parking_lot::Mutex { + fn map(&'a self, f: F) -> U + where + F: FnOnce(parking_lot::MutexGuard<'g, T>) -> U, + 'a: 'g, + { + f(self.lock()) + } +} + +#[cfg(feature = "parking_lot")] +#[derive(Debug, thiserror::Error)] +#[error("Failed to lock the mutex")] +/// Failed to lock the mutex +pub struct LockError; + +#[cfg(feature = "parking_lot")] +impl<'a, 'g, T> super::TryMap<'a, 'g, T, parking_lot::MutexGuard<'g, T>, LockError> + for parking_lot::Mutex +{ + fn try_map(&'a self, f: F) -> Result + where + F: FnOnce(parking_lot::MutexGuard<'g, T>) -> U, + 'a: 'g, + { + match self.try_lock() { + Some(guard) => Ok(f(guard)), + None => Err(LockError), + } + } +} + +impl<'a, 'g, T> + super::TryMap< + 'a, + 'g, + T, + std::sync::MutexGuard<'g, T>, + std::sync::TryLockError>, + > for std::sync::Mutex +{ + fn try_map( + &'a self, + f: F, + ) -> Result>> + where + F: FnOnce(std::sync::MutexGuard<'g, T>) -> U, + 'a: 'g, + { + match self.try_lock() { + Ok(guard) => Ok(f(guard)), + Err(e) => Err(e), + } + } +} diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 42e5333..a045fe6 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -6,6 +6,7 @@ cfg_if::cfg_if! { pub mod flip; pub mod lock; pub mod truncate; + pub mod map; } } @@ -20,6 +21,7 @@ pub mod prelude { pub use super::flip::*; pub use super::lock::*; pub use super::truncate::*; + pub use super::map::*; } }