2

After adding a RefCell to the inside struct, I don't know how to have a reference to only the Rc value.

In other words, I'm creating an Rc<RefCell<T>> but I only need the Rc<T> to be able to downgrade into a Weak.

use std::{
    cell::RefCell,
    fmt,
    rc::{Rc, Weak},
};

#[derive(Debug)]
struct Field {
    i: u8,
    y: u8,
}

impl Field {
    pub fn new() -> Self {
        Self { i: 8, y: 6 }
    }
}

#[derive(Debug)]
pub struct Parent {
    field_1: Field,
    child: RefCell<Option<Child>>,
}

impl Parent {
    pub fn new() -> Rc<RefCell<Self>> {
        let n = Rc::new(RefCell::new(Self {
            field_1: Field::new(),
            child: RefCell::new(None),
        }));

        *n.borrow_mut().child.borrow_mut() = Some(Child::new(&n));

        n
    }

    pub fn modify(&mut self) {
        self.field_1.i = 9;
    }

    pub fn to_string(&self) -> String {
        format!(
            "{:?} {}",
            self.field_1,
            self.child.borrow().as_ref().unwrap()
        )
    }
}

#[derive(Debug)]
pub struct Child {
    parent: Weak<Parent>,
    field_2: Field,
}

impl Child {
    pub fn new(parent: &Rc<Parent>) -> Self {
        Self {
            parent: Rc::downgrade(parent),
            field_2: Field::new(),
        }
    }
}

impl fmt::Display for Child {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.parent.upgrade().unwrap().field_1.i == 1 {
            write!(f, "set: {:?}", self.field_2)
        } else {
            write!(f, "not set {:?}", self.field_2)
        }
    }
}

fn main() {
    let mut parent = Parent::new();
    parent.borrow_mut().modify();
    println!("{}", parent.borrow().to_string());
}

Error:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:32:62
   |
32 |         *n.borrow_mut().child.borrow_mut() = Some(Child::new(&n));
   |                                                              ^^ expected struct `Parent`, found struct `std::cell::RefCell`
   |
   = note: expected reference `&std::rc::Rc<Parent>`
              found reference `&std::rc::Rc<std::cell::RefCell<Parent>>`

I realize that the data structure itself might be the problem, but I currently can't think of a improvement.

0x42
  • 113
  • 2
  • 7
  • 2
    It looks like your question might be answered by the answers of [What is the standard way to call a mutable method in a Rc-wrapped object?](https://stackoverflow.com/q/52994205/155423); [Explain the behavior of *Rc::make_mut and why it differs compared to Mutex](https://stackoverflow.com/q/44012575/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 29 '20 at 15:15
  • Thank you, I'll give these a try. – 0x42 Jun 29 '20 at 15:19

0 Answers0