Crate owned_ref_cell

source ·
Expand description

OwnedRefCell is similar to RefCell, but with a different borrowing mechanism. Unlike RefCell which provides references tied to the lifetimes of the borrow scopes, OwnedRefCell returns special owned references. These references keep the borrowed state until they are explicitly dropped, offering a more flexible way to manage lifetimes especially in complex or dynamic application structures such as event-driven systems or in scenarios where lifetime management is more nuanced.

The main class in this module, OwnedRefCell<T>, provides an interface similar to RefCell<T>, allowing both mutable and immutable borrows, tracked at runtime to ensure that there are no value races. OwnedRefCell<T> should be used when you need temporary mutable access to value inside a value structure that does not itself provide intrinsic mutable access.

Similar to RefCell, this implementation is not thread-safe; it does not implement Sync. If you need thread-safe interior mutability, consider using Mutex, RwLock, or Atomic types.

§Differences from RefCell

  • OwnedRefCell provides OwnedRef and OwnedRefMut, which own their borrow status and thus do not require lifetime annotations.
  • Borrowing rules are enforced at runtime as with RefCell, but OwnedRefCell uses owned types to manage the borrow state instead of lifetimes.
  • While RefCell reacts at runtime with panics when a borrowing rule is violated, OwnedRefCell also offers methods (try_borrow and try_borrow_mut) that return None when a borrow would violate the rules, allowing the caller to react without forcing a panic.

§Examples

Basic usage:

use owned_ref_cell::OwnedRefCell;
use std::collections::HashMap;

let shared_map = OwnedRefCell::new(HashMap::new());

// Create a new block to limit the scope of the dynamic borrow
{
    let mut map = shared_map.borrow_mut();
    map.insert("green", 92388);
    map.insert("blue", 11837);
    map.insert("red", 11826);
    map.insert("yellow", 38);
}

// Note that if we had not let the previous borrow of the cache fall out
// of scope then the subsequent borrow would cause a dynamic thread panic.
// This is the major hazard of using `RefCell`.
let total: i32 = shared_map.borrow().values().sum();
assert_eq!(total, 116089);

// Note that the `OwnedRefMut` outlives the scoped borrow, which would not
// compile as a `RefMut` when using `RefCell`.
let map_ref = {
    let mut map = shared_map.borrow_mut();
    map.insert("purple", 1);
    map
};
let total: i32 = map_ref.values().sum();
assert_eq!(total, 116090);

This module also provides:

  • OwnedRef<T>: an owned, immutable reference to the value inside an OwnedRefCell<T>.
  • OwnedRefMut<T>: an owned, mutable reference to the value inside an OwnedRefCell<T>.

Structs§

  • An immutable reference to the value within OwnedRefCell.
  • Provides mutable or immutable access to encapsulated value with owned references.
  • A mutable reference to the value within OwnedRefCell.