#refcell #nested #ref #no-alloc #refref #refmut

no-std nested-ref

References to data contained in one or more nested RefCells

1 unstable release

0.1.0 May 13, 2023

#1973 in Rust patterns

MIT/Apache

29KB
459 lines

nested-ref

References to data contained in one or more nested RefCells.

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.

Examples

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())
    }
}

License

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.

Dependencies

~245KB