In general, Rc<T> introduces shared ownership of the T, but removes exclusive access to T. &mut _s would be better named exclusive references, as it is undefined behavior to have two active, aliasing &mut _s -- two &mut _s you can use at the same time which point to the same memory.
Because Rc<T> removes exclusive access -- you can have multiple Rc<T>s that give access to the same T -- they cannot hand out &mut Ts. If you need exclusive access -- if you need &mut T -- then Rc<T> on its own won't do the job. You need some way to reintroduce the exclusive access.
RefCell<T> allows for shared mutation of T. It allows getting a &mut T from a &RefCell<T> by using runtime checks to ensure there is never more than one &mut T to the same value.
So when you need to have shared ownership of T but also need to be able to get &mut T, you are generally going to want Rc<RefCell<T>>, or something analogous (Arc<Mutex<T>>, etc).
Here's a longer article about all of that:
The example in the book has RefCell<Vec<Rc<Node>>> inside the Node. The RefCell allows &mut _ access to the Vec<_>, even when the Node is in an Rc<_> -- as they recursively are. It does not allow &mut _ access to the value: i32, or to a Node as a whole, since it is only part of the children field.
The example could be rewritten to have a Vec<Rc<RefCell<Node>>> instead. If one were to do so, it would be possible to get &mut _ access to the value field and to the Nodes as a whole.
So, you should consider what you need &mut _ access to, and think about the "path" to those values through your data structures, keeping in mind that Rc<_> removes the exclusive access and RefCell restores it.
In your latest playground, it looks like you want to be able to modifiy both of these fields:
struct Leaf1 {
branch: RefCell<Weak<Branch>>,
count: u8,
}
You could add a RefCell around the u8 or use AtomicU8, and turn Leaf1's methods back into &self methods. But perhaps what this really means is that you want a RefCell around the entire Leaf1 so you can use your &mut self methods, instead of just the one field inside Leaf1:
struct Leaf1 {
branch: Weak<Branch>,
count: u8,
}
struct Branch {
leaf_1: Rc<Option<RefCell<Leaf1>>>,
leaf_2: Rc<Option<RefCell<Leaf2>>>,
}
I kept your Rc<Option<_>> structure initially. But note that this doesn't allow a &mut _ to the Option<_>. Do you ever need to change those, or not? If not, I'd suggest this instead:
struct Branch {
leaf_1: Option<Rc<RefCell<Leaf1>>>,
leaf_2: Option<Rc<RefCell<Leaf2>>>,
}
That way you don't have to allocate anything extra in the None case, and some things become more ergonomic in the playground.
This is another possibility:
struct Branch {
leaf_1: Rc<RefCell<Option<Leaf1>>>,
leaf_2: Rc<RefCell<Option<Leaf2>>>,
}
This variation does let you get a &mut _ to the Option<_>s. Whether you need that functionality or not is the sort of question Rust forces you to consider up-front, more so than other languages tend to do.