Get a mutable reference to a struct inside an enum

This is a followup to my post Accessing struct methods from their dyn trait binding . The problem is accessing methods for a specific node type when all you have is Box<dyn Node>,

Rather than wrapping the Nodes in Boxes I tried try wrapping in an enum:
enum Node {Chars(CharsNode), And(AndNode), Or(OrNode)... }

I've found I can get a reference to the contents which is in general good enough - the tree is immutable once it is built. During the build phase though there are a few times they may need to be mutable. Is there any way to get a mutable reference to a struct inside an enum? I've tried a bunch of different ways and have not stumbled across one that works.

If nothing else comes up I've implemented clone() on the Node structs so I can get a mutable copy and replace the original in the tree (the mut access only comes at one place, where the parent object is not yet wrapped in the enum). Still, it would be cleaner to modify in place, and I'd like to understand if this is possible.

Something like this?

impl Node {
    fn as_mut_or(&mut self)->Option<&mut OrNode> {
        match self {
            Node::Or(or_node) => Some(or_node),
            _ => None
        }
    }
}

Exactly like that, thanks. I really don't have a good feel for where the mut's, &'s, and lifetimes all belong.

FYI, it's a shortened syntax called "match ergonomics" that results in

  • a mutable reference (self) being accepted in the match against Node::Or, and
  • a mutable reference being produced implicitly from the result of that match

The equivalent explicit way to do the same thing would be either

impl Node {
    fn as_mut_or(&mut self)->Option<&mut OrNode> {
        match self {
            &mut Node::Or(ref mut or_node) => Some(or_node),
            _ => None
        }
    }
}

or

impl Node {
    fn as_mut_or(&mut self)->Option<&mut OrNode> {
        match *self {
            Node::Or(ref mut or_node) => Some(or_node),
            _ => None
        }
    }
}
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.