use option_lock::*;
use std::sync::Arc;
#[test]
fn option_lock_guard() {
let a = OptionLock::from(1);
assert!(!a.is_locked());
let mut guard = a.try_lock().unwrap();
assert!(a.is_locked());
assert_eq!(a.try_lock().unwrap_err(), OptionLockError::Unavailable);
assert_eq!(a.try_take(), Err(OptionLockError::Unavailable));
assert_eq!(guard.as_ref(), Some(&1));
guard.replace(2);
drop(guard);
assert_eq!(a.try_lock().unwrap().as_ref(), Some(&2));
assert!(!a.is_locked());
}
#[test]
fn option_lock_take() {
let a = OptionLock::<u32>::empty();
assert_eq!(a.try_take(), Err(OptionLockError::FillState));
drop(a);
let b = OptionLock::from(101);
assert_eq!(b.try_take(), Ok(101));
drop(b);
}
#[test]
fn option_lock_debug() {
assert_eq!(
format!("{:?}", &OptionLock::<i32>::empty()),
"OptionLock(None)"
);
assert_eq!(format!("{:?}", &OptionLock::from(1)), "OptionLock(Some)");
let lock = OptionLock::from(1);
let guard = lock.try_lock().unwrap();
assert_eq!(format!("{:?}", &guard), "OptionGuard(Some(1))");
assert_eq!(format!("{:?}", &lock), "OptionLock(Locked)");
}
#[test]
fn option_lock_drop() {
use std::sync::atomic::{AtomicUsize, Ordering};
static DROPPED: AtomicUsize = AtomicUsize::new(0);
struct DropCheck;
impl DropCheck {
fn count() -> usize {
DROPPED.load(Ordering::Relaxed)
}
}
impl Drop for DropCheck {
fn drop(&mut self) {
DROPPED.fetch_add(1, Ordering::Release);
}
}
let lock = OptionLock::<DropCheck>::empty();
drop(lock);
assert_eq!(DropCheck::count(), 0);
let lock = OptionLock::from(DropCheck);
drop(lock);
assert_eq!(DropCheck::count(), 1);
let lock = OptionLock::empty();
let mut guard = lock.try_lock().unwrap();
assert_eq!(DropCheck::count(), 1);
guard.replace(DropCheck);
drop(guard);
assert_eq!(DropCheck::count(), 1);
drop(lock);
assert_eq!(DropCheck::count(), 2);
}
#[test]
fn option_lock_try_get() {
let a = OptionLock::from(1);
assert!(!a.is_locked());
let mut guard = a.try_get().unwrap();
assert!(a.is_locked());
assert_eq!(a.try_lock().unwrap_err(), OptionLockError::Unavailable);
assert_eq!(a.try_take(), Err(OptionLockError::Unavailable));
assert_eq!(*guard, 1);
*guard += 1;
drop(guard);
assert_eq!(*a.try_get().unwrap(), 2);
assert!(!a.is_locked());
}
#[test]
fn option_lock_try_clone() {
let a = OptionLock::from(1);
assert_eq!(a.try_clone(), Ok(1));
assert_eq!(a.try_take(), Ok(1));
assert_eq!(a.try_clone(), Err(OptionLockError::FillState));
}
#[test]
fn option_lock_try_copy() {
let a = OptionLock::from(1);
assert_eq!(a.try_copy(), Ok(1));
assert_eq!(a.try_take(), Ok(1));
assert_eq!(a.try_copy(), Err(OptionLockError::FillState));
}
#[test]
fn owned_take() {
let mut lock1 = OptionLock::<()>::empty();
assert_eq!(lock1.take(), None);
let mut lock2 = OptionLock::new(98u32);
assert_eq!(lock2.take(), Some(98u32));
let lock3 = OptionLock::new(99u32);
let val: Option<u32> = lock3.into();
assert_eq!(val, Some(99u32));
}
#[test]
fn owned_replace() {
let mut lock1 = OptionLock::<()>::empty();
assert_eq!(lock1.replace(()), None);
assert_eq!(lock1.replace(()), Some(()));
let mut lock2 = OptionLock::new(18);
assert_eq!(lock2.replace(19), Some(18));
assert_eq!(lock2.replace(20), Some(19));
}
#[test]
fn arc_lock_guard() {
let a = Arc::new(OptionLock::from(1));
assert!(!a.is_locked());
let mut guard = a.try_lock_arc().unwrap();
assert!(a.is_locked());
assert_eq!(a.try_lock().unwrap_err(), OptionLockError::Unavailable);
assert_eq!(a.try_take(), Err(OptionLockError::Unavailable));
assert_eq!(guard.as_ref(), Some(&1));
guard.replace(2);
drop(guard);
assert_eq!(a.try_lock().unwrap().as_ref(), Some(&2));
assert!(!a.is_locked());
}
#[test]
fn arc_lock_try_get() {
let a = Arc::new(OptionLock::from(1));
assert!(!a.is_locked());
let mut guard = a.try_get_arc().unwrap();
assert!(a.is_locked());
assert_eq!(a.try_lock().unwrap_err(), OptionLockError::Unavailable);
assert_eq!(a.try_take(), Err(OptionLockError::Unavailable));
assert_eq!(*guard, 1);
guard.replace(2);
drop(guard);
assert_eq!(a.try_lock().unwrap().as_ref(), Some(&2));
assert!(!a.is_locked());
}
#[test]
fn arc_lock_debug() {
let lock = Arc::new(OptionLock::from(1));
let guard = lock.try_lock_arc().unwrap();
assert_eq!(format!("{:?}", &guard), "OptionGuardArc(Some(1))");
assert_eq!(format!("{:?}", &lock), "OptionLock(Locked)");
drop(guard);
let guard = lock.try_get_arc().unwrap();
assert_eq!(format!("{:?}", &guard), "MutexGuardArc(1)");
}
#[test]
fn arc_lock_drop() {
use std::sync::atomic::{AtomicUsize, Ordering};
static DROPPED: AtomicUsize = AtomicUsize::new(0);
struct DropCheck;
impl DropCheck {
fn count() -> usize {
DROPPED.load(Ordering::Relaxed)
}
}
impl Drop for DropCheck {
fn drop(&mut self) {
DROPPED.fetch_add(1, Ordering::Release);
}
}
let lock = Arc::new(OptionLock::empty());
let mut guard = lock.try_lock_arc().unwrap();
assert_eq!(DropCheck::count(), 0);
guard.replace(DropCheck);
drop(guard);
assert_eq!(DropCheck::count(), 0);
drop(lock);
assert_eq!(DropCheck::count(), 1);
}
#[test]
fn once_cell_set_struct_member() {
struct MyStruct {
param: OnceCell<i32>,
}
impl MyStruct {
pub fn new(value: i32) -> Self {
let slf = Self {
param: Default::default(),
};
slf.param.set(value).unwrap();
slf
}
pub fn get(&self) -> &i32 {
self.param.get().unwrap()
}
}
let s = MyStruct::new(156);
assert_eq!(*s.get(), 156);
assert_eq!(format!("{:?}", &s.param), "OnceCell(Some(156))");
}
#[test]
fn once_cell_get_or_init() {
let cell = OnceCell::empty();
assert_eq!(*cell.get_or_init(|| 10), 10);
assert_eq!(*cell.get_or_init(|| 11), 10);
}
#[test]
fn lazy_static() {
static CELL: Lazy<i32> = Lazy::new(|| 99);
assert_eq!(*CELL, 99);
}