#cell #lifetime #ownership #borrowing #aliasing

lending-cell

Like a cell, but make lifetimes dynamic instead of ownership

3 unstable releases

0.1.1 Jul 14, 2022
0.1.0 Jul 9, 2022
0.0.1 Jul 9, 2022

#8 in #aliasing

Download history 3/week @ 2023-12-18 3/week @ 2024-02-19 35/week @ 2024-02-26 5/week @ 2024-03-04 40/week @ 2024-03-11 11/week @ 2024-03-18 52/week @ 2024-04-01

104 downloads per month
Used in sonnerie

BSD-2-Clause

9KB
64 lines

GitHub license Crates.io docs

LendingCell is a mutable container that allows you to get an owned reference to the same object. When the owned reference is dropped, ownership returns to the original container.

As opposed to a std::cell::Cell which moves Rust's ownership rules to runtime, a LendingCell moves Rust's lifetime rules to runtime.

The value of a LendingCell is present at construction-time, but you can convert it to a BorrowedCell<T> by calling LendingCell::to_borrowed. While that BorrowedCell lives (that is, until it is dropped), calling LendingCell::try_get will return None. The BorrowedCell has exclusive access to your type, as though you have a directly owned instance of the T, and so it is Send as long as T is Send. At last, when you drop the BorrowedCell, the T is returned to the LendingCell.

If you drop your LendingCell before dropping the BorrowedCell, then the T is dropped at the time you drop the BorrowedCell.

The invariants that Rust's memory safety rules enforce, like the single-mutable reference rule, are therefor partially ensured at compile time (you can't get two mutable references to the T), but also partially at runtime (while the BorrowedCell is active, the LendingCell behaves as though it is an Option containing None.

Example

let mut lender = LendingCell::new("borrowed");
let borrowed = lender.to_borrowed();
assert!(lender.try_get().is_none()); // `lender` is empty because it was borrowed
assert_eq!(*borrowed, "borrowed"); // it's certain that `borrowed` is valid while in scope
drop(borrowed); // dropping `borrowed` returns its value to `lender`
assert!(lender.try_get().is_some());

No runtime deps