Expand description
§SlotCell
SlotCell<T> provides move-based interior mutability. It acts as a “Runtime-Checked Move Cell”, providing a alternative to RefCell when you need owned access to data rather than references. It is particularly useful for types that don’t implement Copy or Default, where a standard Cell would be unusable.
Supports no_std.
§Key Features
- Owned Access: Unlike
RefCell, which gives you aRefMutguard,SlotCellallows you to move the value out of the container entirely. - Memory Efficient: Depending on the alignment of
T, it may be smaller thanRefCell. - No Constraints on
T: UnlikeCell<T>, your typeTdoes not need to implementCopy,Clone, orDefault. - Debug Tracking: In debug builds,
SlotCelltracks the file and line number of the last modification. If you try to take a value that is already gone, it tells you exactly where it was taken.
§Comparison with RefCell
| Feature | SlotCell<T> | RefCell<T> |
|---|---|---|
| Access Pattern | Move (Ownership) | Borrow reference (&T / &mut T) |
| Overhead | Occupancy Check (Full/Empty) | Borrow Check (Read/Write) |
| Ergonomics | No lifetime/guard | Uses Ref/RefMut guards |
| Best For | Small/Medium stack types | Large stack types, multiple reads |
§Usage
§Basic Workflow
use slot_cell::SlotCell;
// Create a cell
let cell = SlotCell::new(String::from("Hello"));
let cell_ref: &SlotCell<String> = &cell;
// Take the value (cell is now empty)
let mut s: String = cell_ref.take();
s.push_str(" World");
// Put it back
cell_ref.put(s);
assert_eq!(cell.take(), "Hello World");§Late Initialization
use slot_cell::SlotCell;
let cell = SlotCell::empty();
// ... later ...
cell.put(42);§Performance Considerations
SlotCell is optimized for small stack-allocated values. Because take() and put() move the data:
- Fast: For types bytes (like
i32,String,Vec). - Slower: For very large structs (e.g., arrays), where the cost of moving data exceeds the cost of
RefCell’s reference management. For large types, consider wrapping them in aBoxbefore putting them in aSlotCell.
§Benchmarks
Measured on a standard Criterion suite comparing SlotCell<T>::take/put vs RefCell<T>::borrow_mut.
| Type | Scenario | RefCell (Time) | SlotCell (Time) | Difference |
|---|---|---|---|---|
| - | Access Overhead | 1.31 ns | 586.05 ps | 2.2x Faster |
| i32 (4-byte) | Primitive Update | 1.49 ns | 640.77 ps | 2.3x Faster |
| String (24-byte) | Push Char | 1.34 ns | 5.79 ns | 4.3x Slower |
| Large Struct (~1KB) | Stack Only | 2.24 ns | 132.61 ns | 59x Slower |
| Box<Large Struct> (8-byte) | Heap | 2.24 ns | 2.23 ns | Parity |
§Correctness and Panics
SlotCell is strictly !Sync. It ensures correctness by panicking if:
- You call
take()on an empty cell. - You call
put()on a full cell. - You call
replace()on an empty cell.
In debug mode, these panics include the stack trace/location of the code that previously emptied or filled the slot, making logic errors easy to debug.
Structs§
- Slot
Cell - A cell type that enforces borrowing semantics (take/put) for interior mutability.