#reference #refcell #borrowing #owned #management #mutable #applications

owned_ref_cell

Rust library offering a custom RefCell variant with owned references for flexible and dynamic borrowing management

1 unstable release

0.1.0 May 1, 2024

#16 in #refcell

MIT license

16KB
214 lines

OwnedRefCell

OwnedRefCell is a custom implementation of Rust's RefCell that allows for a different borrowing mechanism. Unlike RefCell which grants references tied to the lifetimes of borrow scopes, OwnedRefCell returns special owned references. These references maintain their borrowed state until they are explicitly dropped, offering more flexibility in managing lifetimes in complex or dynamic application structures.

Tests Lints Docs codecov

The main class in this library, 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.

Features

  • Owned References: Provides OwnedRef and OwnedRefMut, which manage the borrow state internally and allow for dynamic and flexible lifetimes.
  • Safe Borrowing: Ensures safe borrowing at runtime, preventing data races and enabling mutable or immutable access as needed.
  • Easy Integration: Designed to be a drop-in replacement for scenarios where RefCell's lifetime management is too restrictive.

Getting Started

Ensure you have Rust installed on your machine. If not, you can install Rust by following the instructions on the official Rust site.

Installation

Add OwnedRefCell to your Rust project by including it in your Cargo.toml dependencies:

[dependencies]
owned_ref_cell = { git = "https://github.com/snormore/owned_ref_cell.git" }

Usage

Here is a simple example of how to use OwnedRefCell:

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

fn main() {
    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 `OwnedRefCell`.
    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);
}

Documentation

Find more detailed documentation here, or run the following command to generate docs and view them in your browser:

cargo doc --open

Contributing

Contributions are welcome! Please feel free to submit pull requests, create issues for bugs and feature requests, and contribute to improving the documentation.

Support

If you encounter any issues or require assistance, please file an issue on the GitHub repository.

License

This project is licensed under the MIT License - see the LICENSE file for details.

No runtime deps