#refcell #no-alloc

no-std own_or_borrow

Unified references to owned or RefCell borrowed data

2 releases

0.1.1 Dec 2, 2024
0.1.0 Jun 30, 2024

#387 in Embedded development

Download history 15/week @ 2024-09-16 8/week @ 2024-09-23 1/week @ 2024-09-30 140/week @ 2024-12-02 18/week @ 2024-12-09

158 downloads per month

EUPL-1.2

17KB
317 lines

Own or borrow your data.

Crates.io Crates.io GitHub Workflow Status docs.rs codecov

The own-or-borrow crate provides the OwnOrBorrow type, which can encapsulate either owned data or a RefCell-borrowed reference, offering a flexible approach to data ownership and borrowing. This design is particularly useful in no_std environments, as it allows for dynamic borrowing without relying on the standard library.

In contrast, Rust's standard Cow (Clone on Write) type is a smart pointer that enables efficient read-only access to borrowed data and clones the data only when mutation is necessary. It operates with immutable references and requires the ToOwned trait to clone the data when needed.

The key distinction between OwnOrBorrow and Cow lies in their borrowing mechanisms:

  • OwnOrBorrow: Utilizes RefCell to allow for interior mutability, enabling mutable access to borrowed data at runtime. This is advantageous in scenarios where you need to mutate borrowed data without requiring ownership.
  • Cow: Provides immutable access to borrowed data and clones it only when a mutation is required, ensuring that data is not cloned unnecessarily.

Therefore, OwnOrBorrow offers more flexibility in terms of mutability for borrowed data, which can be beneficial in certain use cases, especially in no_std contexts. However, this flexibility comes with the overhead of runtime borrowing checks inherent to RefCell.

Examples

You can create an OwnOrBorrow from an owned value:

use own_or_borrow::OwnOrBorrow;

fn example() {
    let mut value = OwnOrBorrow::own(42);

    assert_eq!(value.borrow().as_ref(), &42);
    assert_eq!(value.borrow_mut().as_mut(), &mut 42);
}

You can create an OwnOrBorrow from a RefCell and treat it the same way:

use own_or_borrow::OwnOrBorrow;
use core::cell::RefCell;

fn example() {
    let refcell = RefCell::new(42);
    let mut value = OwnOrBorrow::from(refcell);

    assert_eq!(value.borrow().as_ref(), &42);
    assert_eq!(value.borrow_mut().as_mut(), &mut 42);
}

Dependencies

~165KB