MutRefStack

Struct MutRefStack 

Source
pub struct MutRefStack<'root, T: ?Sized> { /* private fields */ }

Implementations§

Source§

impl<'root, T: ?Sized> MutRefStack<'root, T>

Source

pub fn new(root: &'root mut T) -> Self

Create a new MutRefStack from a mutable reference to the root of a recursive data structure.

Examples found in repository?
examples/linked_list.rs (line 27)
19fn main() {
20    let mut the_t = SimpleLinkedList {
21        data: 0_u32,
22        child: None,
23    };
24
25    // Using a MutRefStack to descend the data structure.
26    // This could be done with regular mutable references.
27    let mut stack = MutRefStack::new(&mut the_t);
28    for i in 1..10 {
29        stack.top_mut().insert_child(Box::new(SimpleLinkedList {
30            data: i,
31            child: None,
32        }));
33        stack.descend_with(SimpleLinkedList::child_mut).unwrap();
34    }
35    println!("{:?}", the_t);
36
37    // Using regular mutable references to descend the data structure.
38    let mut top = &mut the_t;
39    for i in 1..10 {
40        top.insert_child(Box::new(SimpleLinkedList {
41            data: i,
42            child: None,
43        }));
44        top = top.child_mut().unwrap();
45    }
46    println!("{:?}", the_t);
47
48    // Using a MutRefStack to descend *and then ascend* the data structure.
49    // This cannot be done with regular mutable references.
50    let mut stack = MutRefStack::new(&mut the_t);
51    println!("Stack currently at item with value: {}", stack.top().data);
52    loop {
53        if let None = stack.descend_with(SimpleLinkedList::child_mut) {
54            println!("Reached the end of the linked list!");
55            break;
56        }
57        println!("Descended successfully!");
58        println!("Stack currently at item with value: {}", stack.top().data);
59    }
60    println!("Stack currently at item with value: {}", stack.top().data);
61    loop {
62        if let None = stack.ascend() {
63            println!("Reached the head of the linked list!");
64            break;
65        }
66        println!("Ascended successfully!");
67        println!("Stack currently at item with value: {}", stack.top().data);
68    }
69}
Source

pub fn top(&self) -> &T

Obtain a shared reference to the top of the stack.

Examples found in repository?
examples/linked_list.rs (line 51)
19fn main() {
20    let mut the_t = SimpleLinkedList {
21        data: 0_u32,
22        child: None,
23    };
24
25    // Using a MutRefStack to descend the data structure.
26    // This could be done with regular mutable references.
27    let mut stack = MutRefStack::new(&mut the_t);
28    for i in 1..10 {
29        stack.top_mut().insert_child(Box::new(SimpleLinkedList {
30            data: i,
31            child: None,
32        }));
33        stack.descend_with(SimpleLinkedList::child_mut).unwrap();
34    }
35    println!("{:?}", the_t);
36
37    // Using regular mutable references to descend the data structure.
38    let mut top = &mut the_t;
39    for i in 1..10 {
40        top.insert_child(Box::new(SimpleLinkedList {
41            data: i,
42            child: None,
43        }));
44        top = top.child_mut().unwrap();
45    }
46    println!("{:?}", the_t);
47
48    // Using a MutRefStack to descend *and then ascend* the data structure.
49    // This cannot be done with regular mutable references.
50    let mut stack = MutRefStack::new(&mut the_t);
51    println!("Stack currently at item with value: {}", stack.top().data);
52    loop {
53        if let None = stack.descend_with(SimpleLinkedList::child_mut) {
54            println!("Reached the end of the linked list!");
55            break;
56        }
57        println!("Descended successfully!");
58        println!("Stack currently at item with value: {}", stack.top().data);
59    }
60    println!("Stack currently at item with value: {}", stack.top().data);
61    loop {
62        if let None = stack.ascend() {
63            println!("Reached the head of the linked list!");
64            break;
65        }
66        println!("Ascended successfully!");
67        println!("Stack currently at item with value: {}", stack.top().data);
68    }
69}
Source

pub fn top_mut(&mut self) -> &mut T

Obtain a mutable reference to the top of the stack.

Examples found in repository?
examples/linked_list.rs (line 29)
19fn main() {
20    let mut the_t = SimpleLinkedList {
21        data: 0_u32,
22        child: None,
23    };
24
25    // Using a MutRefStack to descend the data structure.
26    // This could be done with regular mutable references.
27    let mut stack = MutRefStack::new(&mut the_t);
28    for i in 1..10 {
29        stack.top_mut().insert_child(Box::new(SimpleLinkedList {
30            data: i,
31            child: None,
32        }));
33        stack.descend_with(SimpleLinkedList::child_mut).unwrap();
34    }
35    println!("{:?}", the_t);
36
37    // Using regular mutable references to descend the data structure.
38    let mut top = &mut the_t;
39    for i in 1..10 {
40        top.insert_child(Box::new(SimpleLinkedList {
41            data: i,
42            child: None,
43        }));
44        top = top.child_mut().unwrap();
45    }
46    println!("{:?}", the_t);
47
48    // Using a MutRefStack to descend *and then ascend* the data structure.
49    // This cannot be done with regular mutable references.
50    let mut stack = MutRefStack::new(&mut the_t);
51    println!("Stack currently at item with value: {}", stack.top().data);
52    loop {
53        if let None = stack.descend_with(SimpleLinkedList::child_mut) {
54            println!("Reached the end of the linked list!");
55            break;
56        }
57        println!("Descended successfully!");
58        println!("Stack currently at item with value: {}", stack.top().data);
59    }
60    println!("Stack currently at item with value: {}", stack.top().data);
61    loop {
62        if let None = stack.ascend() {
63            println!("Reached the head of the linked list!");
64            break;
65        }
66        println!("Ascended successfully!");
67        println!("Stack currently at item with value: {}", stack.top().data);
68    }
69}
Source

pub fn is_at_root(&self) -> bool

Is this MutRefStack currently at its root?

Source

pub fn inject_top(&mut self, new_top: &'root mut T) -> &mut T

Inject a new reference to the top of the stack. The reference still must live as long as the root of the stack.

Source

pub fn inject_with( &mut self, f: impl FnOnce(&mut T) -> Option<&'root mut T>, ) -> Option<&mut T>

Inject a new reference to the top of the stack. The reference still must live as long as the root of the stack.

Source

pub fn descend_with( &mut self, f: impl for<'node> FnOnce(&'node mut T) -> Option<&'node mut T>, ) -> Option<&mut T>

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?
examples/linked_list.rs (line 33)
19fn main() {
20    let mut the_t = SimpleLinkedList {
21        data: 0_u32,
22        child: None,
23    };
24
25    // Using a MutRefStack to descend the data structure.
26    // This could be done with regular mutable references.
27    let mut stack = MutRefStack::new(&mut the_t);
28    for i in 1..10 {
29        stack.top_mut().insert_child(Box::new(SimpleLinkedList {
30            data: i,
31            child: None,
32        }));
33        stack.descend_with(SimpleLinkedList::child_mut).unwrap();
34    }
35    println!("{:?}", the_t);
36
37    // Using regular mutable references to descend the data structure.
38    let mut top = &mut the_t;
39    for i in 1..10 {
40        top.insert_child(Box::new(SimpleLinkedList {
41            data: i,
42            child: None,
43        }));
44        top = top.child_mut().unwrap();
45    }
46    println!("{:?}", the_t);
47
48    // Using a MutRefStack to descend *and then ascend* the data structure.
49    // This cannot be done with regular mutable references.
50    let mut stack = MutRefStack::new(&mut the_t);
51    println!("Stack currently at item with value: {}", stack.top().data);
52    loop {
53        if let None = stack.descend_with(SimpleLinkedList::child_mut) {
54            println!("Reached the end of the linked list!");
55            break;
56        }
57        println!("Descended successfully!");
58        println!("Stack currently at item with value: {}", stack.top().data);
59    }
60    println!("Stack currently at item with value: {}", stack.top().data);
61    loop {
62        if let None = stack.ascend() {
63            println!("Reached the head of the linked list!");
64            break;
65        }
66        println!("Ascended successfully!");
67        println!("Stack currently at item with value: {}", stack.top().data);
68    }
69}
Source

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?
examples/linked_list.rs (line 62)
19fn main() {
20    let mut the_t = SimpleLinkedList {
21        data: 0_u32,
22        child: None,
23    };
24
25    // Using a MutRefStack to descend the data structure.
26    // This could be done with regular mutable references.
27    let mut stack = MutRefStack::new(&mut the_t);
28    for i in 1..10 {
29        stack.top_mut().insert_child(Box::new(SimpleLinkedList {
30            data: i,
31            child: None,
32        }));
33        stack.descend_with(SimpleLinkedList::child_mut).unwrap();
34    }
35    println!("{:?}", the_t);
36
37    // Using regular mutable references to descend the data structure.
38    let mut top = &mut the_t;
39    for i in 1..10 {
40        top.insert_child(Box::new(SimpleLinkedList {
41            data: i,
42            child: None,
43        }));
44        top = top.child_mut().unwrap();
45    }
46    println!("{:?}", the_t);
47
48    // Using a MutRefStack to descend *and then ascend* the data structure.
49    // This cannot be done with regular mutable references.
50    let mut stack = MutRefStack::new(&mut the_t);
51    println!("Stack currently at item with value: {}", stack.top().data);
52    loop {
53        if let None = stack.descend_with(SimpleLinkedList::child_mut) {
54            println!("Reached the end of the linked list!");
55            break;
56        }
57        println!("Descended successfully!");
58        println!("Stack currently at item with value: {}", stack.top().data);
59    }
60    println!("Stack currently at item with value: {}", stack.top().data);
61    loop {
62        if let None = stack.ascend() {
63            println!("Reached the head of the linked list!");
64            break;
65        }
66        println!("Ascended successfully!");
67        println!("Stack currently at item with value: {}", stack.top().data);
68    }
69}
Source

pub fn ascend_while<P>(&mut self, predicate: P) -> &mut T
where P: FnMut(&mut T) -> bool,

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.

Source

pub fn move_with<F>(&mut self, f: F) -> Result<&mut T, MoveError>
where F: for<'a> FnOnce(&'a mut T) -> MoveDecision<'root, 'a, T>,

Ascend from, descend from, inject a new stack top, or stay at the current node, based on the return value of the closure.

Source

pub async fn move_with_async<F>(&mut self, f: F) -> Result<&mut T, MoveError>
where F: for<'a> FnOnce(&'a mut T) -> Pin<Box<dyn Future<Output = MoveDecision<'root, 'a, T>> + 'a>>,

Source

pub fn into_top(self) -> &'root mut T

Return reference to the top element of this stack, forgetting about the stack entirely.

Source

pub fn to_root(&mut self) -> &mut T

Pop all references off the stack and go back to the root.

Auto Trait Implementations§

§

impl<'root, T> Freeze for MutRefStack<'root, T>
where T: ?Sized,

§

impl<'root, T> RefUnwindSafe for MutRefStack<'root, T>
where T: RefUnwindSafe + ?Sized,

§

impl<'root, T> !Send for MutRefStack<'root, T>

§

impl<'root, T> !Sync for MutRefStack<'root, T>

§

impl<'root, T> Unpin for MutRefStack<'root, T>
where T: ?Sized,

§

impl<'root, T> !UnwindSafe for MutRefStack<'root, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.