1use std::{cell::RefCell, rc::Rc};
2
3use generic_cursors::refcell::RefCellRefMutStack;
4
5#[derive(Debug, Clone)]
6pub struct CyclicDataStructure<T> {
7 data: T,
8 next: Option<Rc<RefCell<Self>>>,
9}
10
11impl<T> CyclicDataStructure<T> {
12 fn next(&mut self) -> Option<&RefCell<Self>> {
13 self.next.as_deref()
14 }
15 fn insert_next(&mut self, new_next: Rc<RefCell<Self>>) -> Option<Rc<RefCell<Self>>> {
16 self.next.replace(new_next)
17 }
18 fn take_next(&mut self) -> Option<Rc<RefCell<Self>>> {
19 self.next.take()
20 }
21}
22
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 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}