use std::mem;
use std::sync::LockResult;
use std::sync::RwLock;
#[derive(Debug, Default)]
pub struct SwapLock<T: Clone>(RwLock<T>);
impl<T: Clone> SwapLock<T> {
pub const fn new(value: T) -> Self {
Self(RwLock::new(value))
}
pub fn get(&self) -> T {
self.handle_poison(self.0.read()).clone()
}
pub fn swap(&self, mut value: T) -> T {
let mut guard = self.handle_poison(self.0.write());
mem::swap(&mut *guard, &mut value);
value
}
pub fn take(&self) -> T
where
T: Default,
{
self.swap(Default::default())
}
fn handle_poison<Guard>(&self, result: LockResult<Guard>) -> Guard {
result.unwrap_or_else(|poison| {
self.0.clear_poison();
poison.into_inner()
})
}
}