Skip to content

Commit

Permalink
added new map trait that replaces LockMap
Browse files Browse the repository at this point in the history
  • Loading branch information
jewlexx committed Dec 4, 2024
1 parent dde85dd commit 25e5483
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
5 changes: 5 additions & 0 deletions src/traits/lock.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
41 changes: 41 additions & 0 deletions src/traits/map.rs
Original file line number Diff line number Diff line change
@@ -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<F, U>(&'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<F, U>(&'a self, f: F) -> Result<U, E>
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<F, U>(&'a self, f: F) -> Result<U, G>
// where
// F: FnOnce(G) -> U + 'g,
// 'a: 'g,
// {
// Ok(self.map(f))
// }
// }
56 changes: 56 additions & 0 deletions src/traits/map/mutex.rs
Original file line number Diff line number Diff line change
@@ -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<T> {
fn map<F, U>(&'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<T>
{
fn try_map<F, U>(&'a self, f: F) -> Result<U, LockError>
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<std::sync::MutexGuard<'g, T>>,
> for std::sync::Mutex<T>
{
fn try_map<F, U>(
&'a self,
f: F,
) -> Result<U, std::sync::TryLockError<std::sync::MutexGuard<'g, T>>>
where
F: FnOnce(std::sync::MutexGuard<'g, T>) -> U,
'a: 'g,
{
match self.try_lock() {
Ok(guard) => Ok(f(guard)),
Err(e) => Err(e),
}
}
}
2 changes: 2 additions & 0 deletions src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ cfg_if::cfg_if! {
pub mod flip;
pub mod lock;
pub mod truncate;
pub mod map;
}
}

Expand All @@ -20,6 +21,7 @@ pub mod prelude {
pub use super::flip::*;
pub use super::lock::*;
pub use super::truncate::*;
pub use super::map::*;
}
}

Expand Down

0 comments on commit 25e5483

Please sign in to comment.