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::::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::::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::::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 = 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, } 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 = Lazy::new(|| 99); assert_eq!(*CELL, 99); }