created_at2023-05-13 14:11:36.764183
updated_at2023-05-13 14:11:36.764183
descriptionReferences to data contained in one or more nested RefCells




References to data contained in one or more nested [RefCell]s.

When borrowing a RefCell that is itself contained in a RefCell, the Refs obtained from either RefCell have to be held onto. [NestedRef] can be used to bundle these nested Refs together, to an arbitrary level of nesting. Only the innermost reference is accessible, via the Deref implementation on NestedRef.

The interface of NestedRef matches that of Ref, with the additional methods [NestedRef::map_ref] and [NestedRef::map_ref_mut] to obtain a reference into a contained RefCell.

For mutable references there is [NestedRefMut], just like RefMut for Ref. Note that only the innermost reference is mutable, the outer references are immutable for both NestedRef and NestedRefMut. Because of this, NestedRefMut cannot be nested further; to obtain a nested mutable reference, create a NestedRef and use map_ref_mut.

This crate is no_std compatible and allocation-free.


use std::cell::RefCell;

use nested_ref::NestedRef;

let rc = RefCell::new(RefCell::new(0));
let nr = NestedRef::new(rc.borrow());
let mut nr = NestedRef::map_ref_mut(nr, RefCell::borrow_mut);
assert_eq!(*nr, 0);
*nr = 1;

Suppose you have a data structure contained in a RefCell, where each entry is also contained in a RefCell. NestedRef allows you to return a reference to the inner data, while holding onto the Refs obtained from both RefCells.

use std::cell::RefCell;

use generic_array::typenum::U1;
use nested_ref::{NestedRef, NestedRefMut};

struct MyVec<T> {
    inner: RefCell<Vec<RefCell<T>>>,

impl<T> MyVec<T> {
    fn get(&self, idx: usize) -> NestedRef<'_, T, U1> {
        let nr = NestedRef::new(self.inner.borrow());
        NestedRef::map_ref(nr, |r| r[idx].borrow())

    fn get_mut(&self, idx: usize) -> NestedRefMut<'_, T, U1> {
        let nr = NestedRef::new(self.inner.borrow());
        NestedRef::map_ref_mut(nr, |r| r[idx].borrow_mut())


Licensed under either of MIT License or Apache License, Version 2.0 at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 1

cargo fmt