#[cfg(feature = "thread-safe")]
use std::sync::{Arc, RwLock};
#[cfg(not(feature = "thread-safe"))]
use std::{cell::RefCell, rc::Rc};
#[cfg(feature = "thread-safe")]
pub type Shared<T> = Arc<T>;
#[cfg(not(feature = "thread-safe"))]
pub type Shared<T> = Rc<T>;
#[cfg(feature = "thread-safe")]
pub type Store<T> = RwLock<T>;
#[cfg(not(feature = "thread-safe"))]
pub type Store<T> = RefCell<T>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shared_can_be_cloned() {
let data = Shared::new(100);
let clone = Shared::clone(&data);
#[cfg(feature = "thread-safe")]
assert_eq!(Arc::strong_count(&data), 2);
#[cfg(not(feature = "thread-safe"))]
assert_eq!(Rc::strong_count(&data), 2);
drop(clone);
#[cfg(feature = "thread-safe")]
assert_eq!(Arc::strong_count(&data), 1);
#[cfg(not(feature = "thread-safe"))]
assert_eq!(Rc::strong_count(&data), 1);
}
#[test]
fn test_store_allows_mutation() {
let store = Store::new(42);
#[cfg(feature = "thread-safe")]
{
{
let value = store.read().unwrap();
assert_eq!(*value, 42);
}
{
let mut value = store.write().unwrap();
*value = 100;
}
{
let value = store.read().unwrap();
assert_eq!(*value, 100);
}
}
#[cfg(not(feature = "thread-safe"))]
{
{
let value = store.borrow();
assert_eq!(*value, 42);
}
{
let mut value = store.borrow_mut();
*value = 100;
}
{
let value = store.borrow();
assert_eq!(*value, 100);
}
}
}
#[test]
fn test_shared_with_store() {
let store = Store::new(vec![1, 2, 3]);
let shared = Shared::new(store);
let clone = Shared::clone(&shared);
#[cfg(feature = "thread-safe")]
{
let data = shared.read().unwrap();
assert_eq!(data.len(), 3);
}
#[cfg(not(feature = "thread-safe"))]
{
let data = shared.borrow();
assert_eq!(data.len(), 3);
}
drop(clone);
}
#[test]
fn test_store_with_string() {
let store = Store::new(String::from("Hello"));
#[cfg(feature = "thread-safe")]
{
let mut value = store.write().unwrap();
value.push_str(", World!");
assert_eq!(*value, "Hello, World!");
}
#[cfg(not(feature = "thread-safe"))]
{
let mut value = store.borrow_mut();
value.push_str(", World!");
assert_eq!(*value, "Hello, World!");
}
}
#[test]
fn test_multiple_shared_references() {
let data = Shared::new(42);
let refs: Vec<_> = (0..5).map(|_| Shared::clone(&data)).collect();
#[cfg(feature = "thread-safe")]
assert_eq!(Arc::strong_count(&data), 6);
#[cfg(not(feature = "thread-safe"))]
assert_eq!(Rc::strong_count(&data), 6);
drop(refs);
#[cfg(feature = "thread-safe")]
assert_eq!(Arc::strong_count(&data), 1);
#[cfg(not(feature = "thread-safe"))]
assert_eq!(Rc::strong_count(&data), 1);
}
}