use generational_box::{GenerationalBox, Storage, SyncStorage, UnsyncStorage}; /// # Example /// /// ```compile_fail /// let data = String::from("hello world"); /// let owner = UnsyncStorage::owner(); /// let key = owner.insert(&data); /// drop(data); /// assert_eq!(*key.read(), "hello world"); /// ``` #[allow(unused)] fn compile_fail() {} #[test] fn leaking_is_ok() { fn leaking_is_ok_test>() { let data = String::from("hello world"); let key; { // create an owner let owner = S::owner(); // insert data into the store key = owner.insert(data); // don't drop the owner std::mem::forget(owner); } assert_eq!( key.try_read().as_deref().unwrap(), &"hello world".to_string() ); } leaking_is_ok_test::(); leaking_is_ok_test::(); } #[test] fn drops() { fn drops_test>() { let data = String::from("hello world"); let key; { // create an owner let owner = S::owner(); // insert data into the store key = owner.insert(data); // drop the owner } assert!(key.try_read().is_err()); } drops_test::(); drops_test::(); } #[test] fn works() { fn works_test>() { let owner = S::owner(); let key = owner.insert(1); assert_eq!(*key.read(), 1); } works_test::(); works_test::(); } #[test] fn insert_while_reading() { fn insert_while_reading_test + Storage<&'static i32>>() { let owner = S::owner(); let key; { let data: String = "hello world".to_string(); key = owner.insert(data); } let value = key.read(); owner.insert(&1); assert_eq!(*value, "hello world"); } insert_while_reading_test::(); insert_while_reading_test::(); } #[test] #[should_panic] fn panics() { fn panics_test>() { let owner = S::owner(); let key = owner.insert(1); drop(owner); assert_eq!(*key.read(), 1); } panics_test::(); panics_test::(); } #[test] fn fuzz() { fn maybe_owner_scope>( valid_keys: &mut Vec>, invalid_keys: &mut Vec>, path: &mut Vec, ) { let branch_cutoff = 5; let children = if path.len() < branch_cutoff { rand::random::() % 4 } else { rand::random::() % 2 }; for i in 0..children { let owner = S::owner(); let key = owner.insert(format!("hello world {path:?}")); println!("created new box {key:?}"); valid_keys.push(key); path.push(i); // read all keys println!("{:?}", path); for key in valid_keys.iter() { println!("reading {key:?}"); let value = key.read(); println!("{:?}", &*value); assert!(value.starts_with("hello world")); } for key in invalid_keys.iter() { println!("reading invalid {key:?}"); assert!(key.try_read().is_err()); } maybe_owner_scope(valid_keys, invalid_keys, path); let invalid = valid_keys.pop().unwrap(); println!("popping {invalid:?}"); invalid_keys.push(invalid); path.pop(); } } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } for _ in 0..10 { maybe_owner_scope::(&mut Vec::new(), &mut Vec::new(), &mut Vec::new()); } }