use std::sync::Arc;
use parking_lot::RwLock;
use super::user::User;
pub struct UserHandle {
user: RwLock<Arc<User>>,
}
impl UserHandle {
pub fn new(user: Arc<User>) -> Self {
Self {
user: RwLock::new(user),
}
}
pub fn user(&self) -> Arc<User> {
self.user.read().clone()
}
pub fn try_set_user(&self, new_user: Arc<User>, expected: &Arc<User>) -> bool {
let mut slot = self.user.write();
if Arc::ptr_eq(&slot, expected) {
*slot = new_user;
true
} else {
false
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn try_set_user_swaps_only_matching_instance() {
let u1 = Arc::new(User::new("a".into()));
let u2 = Arc::new(User::new("a".into()));
let h = UserHandle::new(u1.clone());
assert!(Arc::ptr_eq(&h.user(), &u1));
assert!(!h.try_set_user(u2.clone(), &u2));
assert!(Arc::ptr_eq(&h.user(), &u1));
assert!(h.try_set_user(u2.clone(), &u1));
assert!(Arc::ptr_eq(&h.user(), &u2));
}
}