use crate::*;
const DEFAULT_TRY_LOCK: bool = false;
const DEFAULT_SILENT_UNLOCK: bool = false;
struct HangLock(Box<dyn ConcreteLock>);
impl Lock for HangLock {
fn status(&self) -> SimpleLockResult<LockStatus> {
self.0.status()
}
fn lock(&mut self) -> SimpleLockResult<()> {
self.0.hang_lock()
}
fn unlock(&mut self) -> SimpleLockResult<()> {
self.0.try_unlock()
}
}
struct TryLock(Box<dyn ConcreteLock>);
impl Lock for TryLock {
fn status(&self) -> SimpleLockResult<LockStatus> {
self.0.status()
}
fn lock(&mut self) -> SimpleLockResult<()> {
self.0.try_lock()
}
fn unlock(&mut self) -> SimpleLockResult<()> {
self.0.try_unlock()
}
}
struct SilentUnlocker(Box<dyn Lock>);
impl Lock for SilentUnlocker {
fn status(&self) -> SimpleLockResult<LockStatus> {
self.0.status()
}
fn lock(&mut self) -> SimpleLockResult<()> {
self.0.lock()
}
fn unlock(&mut self) -> SimpleLockResult<()> {
let _ = self.0.unlock();
Ok(())
}
}
#[derive(Copy, Clone, Debug)]
pub struct LockBuilder {
try_lock: bool,
silent_unlock: bool, }
impl Default for LockBuilder {
fn default() -> Self {
LockBuilder {
try_lock: DEFAULT_TRY_LOCK,
silent_unlock: DEFAULT_SILENT_UNLOCK,
}
}
}
impl LockBuilder {
pub fn enable_silent_unlock(mut self) {
self.silent_unlock = true;
}
pub fn enable_try_lock(mut self) {
self.try_lock = true;
}
pub fn with_silent_unlock(self) -> Self {
self.enable_silent_unlock();
self
}
pub fn with_try_lock(self) -> Self {
self.enable_try_lock();
self
}
pub fn wrap(&self, concrete: Box<dyn ConcreteLock>) -> SimpleLockResult<Box<dyn Lock>> {
let lock: Box<dyn Lock> = if self.try_lock {
Box::new(TryLock(concrete))
} else {
Box::new(HangLock(concrete))
};
if self.silent_unlock {
Ok(Box::new(SilentUnlocker(lock)))
} else {
Ok(lock)
}
}
#[allow(unused_variables)]
pub fn build(&self, app_name: impl Into<String>) -> SimpleLockResult<Box<dyn Lock>> {
cfg_if! {
if #[cfg(feature = "file")] {
let path = format!("/tmp/lock-{}", app_name.into());
self.wrap(Box::new(FileLock::new(path)?))
} else if #[cfg(feature = "sema")] {
self.wrap(Box::new(SemaphoreLock::new(app_name)?))
} else if #[cfg(feature = "fake")] {
Ok(Box::new(FakeLock::default()))
} else {
Err(SimpleLockError::NoLockEnabled)
}
}
}
}