# Shared Container
A unified abstraction for shared data access in both multi-threaded and single-threaded environments.
[](https://crates.io/crates/shared-container)
[](https://docs.rs/shared-container)
[](https://opensource.org/licenses/MIT)
## Overview
`shared-container` provides a unified abstraction over different container types used for shared data access with interior mutability in different contexts. It abstracts over the differences between:
- Thread-safe `Arc<RwLock<T>>` used in multi-threaded environments
- `Rc<RefCell<T>>` used in single-threaded environments like WebAssembly
This allows code using these containers to be written once but work efficiently in both contexts.
## Features
- **Platform-aware implementation**: Automatically uses the most efficient implementation based on the target platform
- **Unified API**: Same API for both multi-threaded and single-threaded environments
- **Read/Write access**: Provides both read-only and read-write access to the contained data
- **Weak references**: Supports weak references to prevent reference cycles
- **Clone support**: Containers can be cloned to create multiple references to the same data
- **Transparent access**: Uses Rust's deref mechanism for ergonomic access to the contained data
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
shared-container = "0.1.0"
```
### Basic Example
```rust
use shared_container::SharedContainer;
// Create a new container with a value
let container = SharedContainer::new(42);
// Read access
if let Some(guard) = container.read() {
println!("Value: {}", *guard);
}
// Write access
if let Some(mut guard) = container.write() {
*guard = 100;
}
// Clone the container (both point to the same data)
let container2 = container.clone();
// Changes through one container are visible through the other
if let Some(guard) = container2.read() {
assert_eq!(*guard, 100);
}
// Create a weak reference
let weak = container.downgrade();
// Upgrade weak reference to strong reference
if let Some(container3) = weak.upgrade() {
// Use container3...
}
```
### Working with Custom Types
```rust
use shared_container::SharedContainer;
use std::fmt::Debug;
#[derive(Debug, Clone)]
struct User {
id: u64,
name: String,
}
let user = User {
id: 1,
name: "Alice".to_string(),
};
let container = SharedContainer::new(user);
// Get a clone of the contained value
if let Some(user_clone) = container.get_cloned() {
println!("User: {:?}", user_clone);
}
// Modify the user
if let Some(mut guard) = container.write() {
guard.name = "Bob".to_string();
}
```
## Platform-specific Behavior
- On native platforms, `SharedContainer<T>` uses `Arc<RwLock<T>>` internally
- On WebAssembly (`wasm32` target), it uses `Rc<RefCell<T>>` internally
- The API remains the same, but the behavior differs slightly:
- On native platforms, read/write operations can fail if the lock is poisoned
- On WebAssembly, read/write operations can fail if there's already a borrow
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.