pub struct RefCellRefMutStack<'root, T: ?Sized> { /* private fields */ }Implementations§
Source§impl<'root, T: ?Sized> RefCellRefMutStack<'root, T>
impl<'root, T: ?Sized> RefCellRefMutStack<'root, T>
Sourcepub fn new(root: &'root RefCell<T>) -> Result<Self, BorrowMutError>
pub fn new(root: &'root RefCell<T>) -> Result<Self, BorrowMutError>
Create a new MutRefStack from a mutable reference to the root of a recursive data structure.
Examples found in repository?
23fn main() {
24 let cycle_a = Rc::new(RefCell::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let cycle_b = Rc::new(RefCell::new(CyclicDataStructure {
29 data: 1_u32,
30 next: None,
31 }));
32 let cycle_c = Rc::new(RefCell::new(CyclicDataStructure {
33 data: 2_u32,
34 next: None,
35 }));
36
37 cycle_a.borrow_mut().insert_next(cycle_b.clone());
38 cycle_b.borrow_mut().insert_next(cycle_c.clone());
39 cycle_c.borrow_mut().insert_next(cycle_a.clone());
40
41 // Using a MutRefStack to descend *and then ascend* the data structure.
42 // This cannot be done with regular mutable references.
43 let mut stack = RefCellRefMutStack::new(&cycle_a).expect("not mutable borrowed yet");
44 println!("Stack currently at item with value: {}", stack.top().data);
45 loop {
46 if let Err(_borrow_error) = stack
47 .descend_with(CyclicDataStructure::next)
48 .expect("no node has no next")
49 {
50 println!("Found a cycle!");
51 break;
52 }
53 println!("Descended successfully!");
54 println!("Stack currently at item with value: {}", stack.top().data);
55 }
56 println!("Stack currently at item with value: {}", stack.top().data);
57 loop {
58 if let None = stack.ascend() {
59 println!("Reached the head of the linked list!");
60 break;
61 }
62 println!("Ascended successfully!");
63 println!("Stack currently at item with value: {}", stack.top().data);
64 }
65
66 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
67 stack.top_mut().take_next();
68}pub fn raw_top_mut(&mut self) -> *mut T
Sourcepub fn top(&self) -> &T
pub fn top(&self) -> &T
Obtain a shared reference to the top of the stack.
Examples found in repository?
23fn main() {
24 let cycle_a = Rc::new(RefCell::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let cycle_b = Rc::new(RefCell::new(CyclicDataStructure {
29 data: 1_u32,
30 next: None,
31 }));
32 let cycle_c = Rc::new(RefCell::new(CyclicDataStructure {
33 data: 2_u32,
34 next: None,
35 }));
36
37 cycle_a.borrow_mut().insert_next(cycle_b.clone());
38 cycle_b.borrow_mut().insert_next(cycle_c.clone());
39 cycle_c.borrow_mut().insert_next(cycle_a.clone());
40
41 // Using a MutRefStack to descend *and then ascend* the data structure.
42 // This cannot be done with regular mutable references.
43 let mut stack = RefCellRefMutStack::new(&cycle_a).expect("not mutable borrowed yet");
44 println!("Stack currently at item with value: {}", stack.top().data);
45 loop {
46 if let Err(_borrow_error) = stack
47 .descend_with(CyclicDataStructure::next)
48 .expect("no node has no next")
49 {
50 println!("Found a cycle!");
51 break;
52 }
53 println!("Descended successfully!");
54 println!("Stack currently at item with value: {}", stack.top().data);
55 }
56 println!("Stack currently at item with value: {}", stack.top().data);
57 loop {
58 if let None = stack.ascend() {
59 println!("Reached the head of the linked list!");
60 break;
61 }
62 println!("Ascended successfully!");
63 println!("Stack currently at item with value: {}", stack.top().data);
64 }
65
66 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
67 stack.top_mut().take_next();
68}Sourcepub fn top_mut(&mut self) -> &mut T
pub fn top_mut(&mut self) -> &mut T
Obtain a mutable reference to the top of the stack.
Examples found in repository?
23fn main() {
24 let cycle_a = Rc::new(RefCell::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let cycle_b = Rc::new(RefCell::new(CyclicDataStructure {
29 data: 1_u32,
30 next: None,
31 }));
32 let cycle_c = Rc::new(RefCell::new(CyclicDataStructure {
33 data: 2_u32,
34 next: None,
35 }));
36
37 cycle_a.borrow_mut().insert_next(cycle_b.clone());
38 cycle_b.borrow_mut().insert_next(cycle_c.clone());
39 cycle_c.borrow_mut().insert_next(cycle_a.clone());
40
41 // Using a MutRefStack to descend *and then ascend* the data structure.
42 // This cannot be done with regular mutable references.
43 let mut stack = RefCellRefMutStack::new(&cycle_a).expect("not mutable borrowed yet");
44 println!("Stack currently at item with value: {}", stack.top().data);
45 loop {
46 if let Err(_borrow_error) = stack
47 .descend_with(CyclicDataStructure::next)
48 .expect("no node has no next")
49 {
50 println!("Found a cycle!");
51 break;
52 }
53 println!("Descended successfully!");
54 println!("Stack currently at item with value: {}", stack.top().data);
55 }
56 println!("Stack currently at item with value: {}", stack.top().data);
57 loop {
58 if let None = stack.ascend() {
59 println!("Reached the head of the linked list!");
60 break;
61 }
62 println!("Ascended successfully!");
63 println!("Stack currently at item with value: {}", stack.top().data);
64 }
65
66 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
67 stack.top_mut().take_next();
68}Sourcepub fn is_at_root(&self) -> bool
pub fn is_at_root(&self) -> bool
Is this MutRefStack currently at its root?
Sourcepub fn inject_top(
&mut self,
new_top: &'root RefCell<T>,
) -> Result<&mut T, BorrowMutError>
pub fn inject_top( &mut self, new_top: &'root RefCell<T>, ) -> Result<&mut T, BorrowMutError>
Inject a new reference to the top of the stack. The reference still must live as long as the root of the stack.
Sourcepub fn inject_with(
&mut self,
f: impl FnOnce(&mut T) -> Option<&'root RefCell<T>>,
) -> Option<Result<&mut T, BorrowMutError>>
pub fn inject_with( &mut self, f: impl FnOnce(&mut T) -> Option<&'root RefCell<T>>, ) -> Option<Result<&mut T, BorrowMutError>>
Inject a new reference to the top of the stack. The reference still must live as long as the root of the stack.
Sourcepub fn descend_with(
&mut self,
f: impl for<'node> FnOnce(&'node mut T) -> Option<&'node RefCell<T>>,
) -> Option<Result<&mut T, BorrowMutError>>
pub fn descend_with( &mut self, f: impl for<'node> FnOnce(&'node mut T) -> Option<&'node RefCell<T>>, ) -> Option<Result<&mut T, BorrowMutError>>
Descend into the recursive data structure, returning a mutable reference to the new top element.
Rust’s borrow checker enforces that the closure cannot inject any lifetime (other than 'static),
because the closure must work for any lifetime 'node.
Examples found in repository?
23fn main() {
24 let cycle_a = Rc::new(RefCell::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let cycle_b = Rc::new(RefCell::new(CyclicDataStructure {
29 data: 1_u32,
30 next: None,
31 }));
32 let cycle_c = Rc::new(RefCell::new(CyclicDataStructure {
33 data: 2_u32,
34 next: None,
35 }));
36
37 cycle_a.borrow_mut().insert_next(cycle_b.clone());
38 cycle_b.borrow_mut().insert_next(cycle_c.clone());
39 cycle_c.borrow_mut().insert_next(cycle_a.clone());
40
41 // Using a MutRefStack to descend *and then ascend* the data structure.
42 // This cannot be done with regular mutable references.
43 let mut stack = RefCellRefMutStack::new(&cycle_a).expect("not mutable borrowed yet");
44 println!("Stack currently at item with value: {}", stack.top().data);
45 loop {
46 if let Err(_borrow_error) = stack
47 .descend_with(CyclicDataStructure::next)
48 .expect("no node has no next")
49 {
50 println!("Found a cycle!");
51 break;
52 }
53 println!("Descended successfully!");
54 println!("Stack currently at item with value: {}", stack.top().data);
55 }
56 println!("Stack currently at item with value: {}", stack.top().data);
57 loop {
58 if let None = stack.ascend() {
59 println!("Reached the head of the linked list!");
60 break;
61 }
62 println!("Ascended successfully!");
63 println!("Stack currently at item with value: {}", stack.top().data);
64 }
65
66 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
67 stack.top_mut().take_next();
68}Sourcepub fn ascend(&mut self) -> Option<&mut T>
pub fn ascend(&mut self) -> Option<&mut T>
Ascend back up from the recursive data structure, returning a mutable reference to the new top element, if it changed. If we are not currently at the root, ascend and return a reference to the new top. If we are already at the root, returns None (the top is the root and does not change).
Examples found in repository?
23fn main() {
24 let cycle_a = Rc::new(RefCell::new(CyclicDataStructure {
25 data: 0_u32,
26 next: None,
27 }));
28 let cycle_b = Rc::new(RefCell::new(CyclicDataStructure {
29 data: 1_u32,
30 next: None,
31 }));
32 let cycle_c = Rc::new(RefCell::new(CyclicDataStructure {
33 data: 2_u32,
34 next: None,
35 }));
36
37 cycle_a.borrow_mut().insert_next(cycle_b.clone());
38 cycle_b.borrow_mut().insert_next(cycle_c.clone());
39 cycle_c.borrow_mut().insert_next(cycle_a.clone());
40
41 // Using a MutRefStack to descend *and then ascend* the data structure.
42 // This cannot be done with regular mutable references.
43 let mut stack = RefCellRefMutStack::new(&cycle_a).expect("not mutable borrowed yet");
44 println!("Stack currently at item with value: {}", stack.top().data);
45 loop {
46 if let Err(_borrow_error) = stack
47 .descend_with(CyclicDataStructure::next)
48 .expect("no node has no next")
49 {
50 println!("Found a cycle!");
51 break;
52 }
53 println!("Descended successfully!");
54 println!("Stack currently at item with value: {}", stack.top().data);
55 }
56 println!("Stack currently at item with value: {}", stack.top().data);
57 loop {
58 if let None = stack.ascend() {
59 println!("Reached the head of the linked list!");
60 break;
61 }
62 println!("Ascended successfully!");
63 println!("Stack currently at item with value: {}", stack.top().data);
64 }
65
66 println!("(Breaking the cycle to prevent miri from complaining about memory leaks)");
67 stack.top_mut().take_next();
68}Sourcepub fn ascend_while<P>(&mut self, predicate: P) -> &mut T
pub fn ascend_while<P>(&mut self, predicate: P) -> &mut T
Ascend back up from the recursive data structure while the given closure returns true, returning a mutable reference to the new top element.
If we are not currently at the root, and the predicate returns true, ascend and continue.
If we are already at the root, or if the predicate returned false, returns a reference to the top element.
Sourcepub fn move_with<F>(&mut self, f: F) -> Result<&mut T, MoveError>
pub fn move_with<F>(&mut self, f: F) -> Result<&mut T, MoveError>
Ascend from, descend from, inject a new stack top, or stay at the current node, based on the return value of the closure.