Hello every one,
I don't exactly know why my weak reference in that case is upgraded as None at line 18...
since the reference is supposed to be valid ...
what I miss ?
if some one can help please it's very important for me.
use dtb::*;
fn main() {
let mut data_base = config_tree();
data_base.branch_at_right(Some("hello !"));
data_base.go_to_right();
//data_base.branch_at_right(Some("too hard !"));
//data_base.go_to_right();
println!(
"current previous value: {:?}",
data_base
.current
.as_ref()
.unwrap()
.borrow_mut()
.upgrade_previous() //<<<<<<<< line 18
.ok()
);
// Dsiplay the tree.
println!(
"\n--->{:?}\nSize on ram: {} Bytes (from the current node only)\n",
data_base,
data_base.size_on_ram().unwrap()
);
println!(
"Current value: {:?}",
data_base.current.as_ref().unwrap().borrow().value
);
}
pub mod dtb {
use std::cell::RefCell;
use std::rc::{Rc, Weak};
type Link = Rc<RefCell<Node>>;
type WeakLink = Weak<RefCell<Node>>;
#[derive(Debug)]
pub struct Node {
pub value: Option<String>,
pub left: Option<Link>,
pub right: Option<Link>,
pub prev: Option<WeakLink>,
}
impl Node {
pub fn new_tree(value: Option<&str>) -> Link {
let mut tmp: Option<String> = None;
if let Some(str) = value {
tmp = Some(String::from(str));
} // just convert an Option<&str> to Option<String>.
Rc::new(RefCell::new(Node {
value: tmp,
left: None,
right: None,
prev: None,
}))
}
fn _is_root(&self) -> bool {
if self.value == Some(String::from("root")) {
true
} else {
false
}
}
/// provide an upgraded previous Link.
pub fn upgrade_previous(&mut self) -> Result<Link, &str> {
if let Some(a) = self.prev.clone() {
if let Some(b) = Weak::upgrade(&a) {
Ok(b)
} else {
Err("Error, previous link not valid !")
}
} else {
Err("prev = None")
}
}
fn sum_all_bytes(&self) -> usize {
let (mut tmp1, mut tmp2) = (0usize, 0usize);
if let Some(left) = &self.left {
tmp1 = left.borrow().sum_all_bytes();
}
if let Some(right) = &self.right {
tmp2 = right.borrow().sum_all_bytes();
}
if let Some(a) = &self.value {
a.len() + tmp1 + tmp2 + std::mem::size_of::<Node>()
} else {
0usize + tmp1 + tmp2 + std::mem::size_of::<Node>()
}
}
}
#[derive(Debug)]
pub struct Tree {
pub current: Option<Link>,
pub root: Option<WeakLink>,
}
impl Tree {
pub fn branch_at_right(&mut self, value: Option<&str>) {
// if node is root.
if let Some(a) = &self.current {
let new_block = Node::new_tree(value);
let mut current = Node::new_tree(None);
if a.borrow()._is_root() {
// first get the current with indirection Rc<Refcell<Node>> awarness not just node.
current = a.borrow_mut().upgrade_previous().ok().unwrap();
} else {
// first get the current with awarness
let prev = a.borrow_mut().upgrade_previous().ok().unwrap();
// then n+1 since this node is not root.
current = prev.borrow_mut().right.as_ref().unwrap().clone();
}
// update the new_block.prev
new_block.borrow_mut().prev = Some(Rc::downgrade(¤t.clone()));
// insert the new block
a.borrow_mut().right = Some(new_block.clone());
println!(
"Insert in node :\n{:?}\n The previous node : \n{:?}\n",
a.borrow().right,
current
);
}
}
fn tree_init_step1(current_init_value: Option<&str>) -> Self {
Self {
current: Some(Node::new_tree(current_init_value)),
root: None,
}
}
fn tree_init_step2(&mut self) {
if let Some(a) = &self.current {
a.borrow_mut().prev = Some(Rc::downgrade(a));
}
if let None = self.root {
if let Some(b) = &self.current {
self.root = Some(Rc::downgrade(b));
}
}
}
pub fn size_on_ram(&self) -> Result<usize, &str> {
if let Some(current) = &self.current {
Ok(current.borrow_mut().sum_all_bytes() + std::mem::size_of::<Tree>())
} else {
Err("Data base Tree non initialized: run fn config_tree() first !")
}
}
pub fn goback_to_root(&mut self) {
if let Some(root) = &self.root {
self.current = Some(Weak::upgrade(root).as_ref().unwrap().clone());
} else {
eprintln!("Error! root Link is None");
}
}
pub fn go_to_left(&mut self) {
if let Some(current) = self.current.take() {
self.current = current.borrow_mut().left.clone();
} else {
eprintln!("No left branch to move on !");
}
}
pub fn go_to_right(&mut self) {
if let Some(current) = self.current.take() {
self.current = current.borrow_mut().right.clone();
} else {
eprintln!("No right branch to move on !");
}
}
pub fn go_to_previous(&mut self) {
if let Some(a) = self.current.clone() {
if let Some(b) = a.borrow_mut().prev.clone() {
if let Some(prev) = Weak::upgrade(&b) {
self.current = Some(prev);
} else {
println!("fail to upgrade")
}
}
}
}
}
pub fn config_tree() -> Tree {
let mut db = Tree::tree_init_step1(Some("root"));
db.tree_init_step2();
db
}
}