use std::cell::Cell;
use std::ptr;
use std::rc::Rc;
use get_mut_drop_weak::rc::get_mut_drop_weak;
#[test]
fn test_exclusive_access_no_weak() {
let mut rc = Rc::new(10);
let original_ptr = Rc::as_ptr(&rc);
let result = get_mut_drop_weak(&mut rc);
let val_mut = result.unwrap(); assert_eq!(*val_mut, 10);
*val_mut = 20;
assert_eq!(*rc, 20);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(Rc::weak_count(&rc), 0);
assert_eq!(Rc::as_ptr(&rc), original_ptr);
}
#[test]
fn test_strong_shared_no_mut() {
let mut rc1 = Rc::new(String::from("hello"));
let rc2 = Rc::clone(&rc1);
let original_ptr = Rc::as_ptr(&rc1);
assert_eq!(Rc::strong_count(&rc1), 2);
let result = get_mut_drop_weak(&mut rc1);
let err_ref = result.unwrap_err(); assert!(ptr::eq(err_ref, &rc1));
assert_eq!(*rc1, "hello");
assert_eq!(*rc2, "hello");
assert_eq!(Rc::strong_count(&rc1), 2);
assert_eq!(Rc::weak_count(&rc1), 0);
assert_eq!(Rc::as_ptr(&rc1), original_ptr);
drop(rc2);
assert_eq!(Rc::strong_count(&rc1), 1);
}
#[test]
fn test_strong_shared_with_weak_no_mut() {
let mut rc1 = Rc::new(vec![1, 2, 3]);
let rc2 = Rc::clone(&rc1);
let weak1 = Rc::downgrade(&rc1);
let original_ptr = Rc::as_ptr(&rc1);
assert_eq!(Rc::strong_count(&rc1), 2);
assert_eq!(Rc::weak_count(&rc1), 1);
assert!(weak1.upgrade().is_some());
let result = get_mut_drop_weak(&mut rc1);
let err_ref = result.unwrap_err(); assert!(ptr::eq(err_ref, &rc1));
assert_eq!(*rc1, vec![1, 2, 3]);
assert_eq!(*rc2, vec![1, 2, 3]);
assert_eq!(Rc::strong_count(&rc1), 2);
assert_eq!(Rc::weak_count(&rc1), 1);
assert!(weak1.upgrade().is_some()); assert_eq!(Rc::as_ptr(&rc1), original_ptr);
drop(rc2);
assert_eq!(Rc::strong_count(&rc1), 1);
assert_eq!(Rc::weak_count(&rc1), 1); }
#[test]
fn test_weak_shared_drops_weak_success() {
#[derive(Debug, PartialEq)]
struct TestData {
value: i32,
}
let mut rc = Rc::new(TestData { value: 50 });
let weak1 = Rc::downgrade(&rc);
let weak2 = Rc::downgrade(&rc);
let original_ptr = Rc::as_ptr(&rc);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(Rc::weak_count(&rc), 2);
assert!(weak1.upgrade().is_some());
assert!(weak2.upgrade().is_some());
let result = get_mut_drop_weak(&mut rc);
let val_mut = result.unwrap(); assert_eq!(val_mut.value, 50);
val_mut.value = 60;
assert_eq!(rc.value, 60);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(Rc::weak_count(&rc), 0);
let new_ptr = Rc::as_ptr(&rc);
assert_ne!(new_ptr, original_ptr);
assert!(weak1.upgrade().is_none());
assert!(weak2.upgrade().is_none());
}
#[derive(Debug)]
struct DropTracker<'a> {
id: i32,
dropped: &'a Cell<bool>,
}
impl<'a> Drop for DropTracker<'a> {
fn drop(&mut self) {
println!("Dropping DropTracker id: {}", self.id);
self.dropped.set(true);
}
}
#[test]
fn test_weak_shared_drops_weak_with_drop_impl() {
let dropped_flag = Cell::new(false);
let data = DropTracker {
id: 1,
dropped: &dropped_flag,
};
let mut rc = Rc::new(data);
let weak = Rc::downgrade(&rc);
let original_ptr = Rc::as_ptr(&rc);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(Rc::weak_count(&rc), 1);
assert!(!dropped_flag.get());
let result = get_mut_drop_weak(&mut rc);
let val_mut = result.unwrap();
val_mut.id = 2;
assert_eq!(val_mut.id, 2);
assert_eq!(Rc::strong_count(&rc), 1);
assert_eq!(Rc::weak_count(&rc), 0); assert_ne!(Rc::as_ptr(&rc), original_ptr); assert!(weak.upgrade().is_none()); assert!(!dropped_flag.get());
drop(rc);
assert!(dropped_flag.get()); }