Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust: How to add element to vector and return reference to that element?

I am trying my hand at a simple XML writer in Rust by first building a tree of tags in memory.

In the function add_child below, I want to add the newly created child element to the current element’s list of children, then return that child so that the caller can in turn add other children to that child. But I can’t, because the child is then owned by the vector.

What is the "idiomatic" way to do this sort of thing in Rust?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I suppose I could let the consumer of my tag.rs library manipulate the list of children in the struct themselves, but then the implementation details are not neatly contained in a function.

Is there another/better way to do this?

// tag.rs
use std::collections::HashMap;

pub struct Tag<'a> {
    name: &'a str,
    attributes: HashMap<&'a str, &'a str>,
    children: Vec<Tag<'a>>,
}

impl<'a> Tag<'a> {
    pub fn new(name: &'a str) -> Self {
        Self {
            name,
            attributes: HashMap::new(),
            children: vec![],
        }
    }

    pub fn add_child(&mut self, name: &'a str) -> Self {
        let mut child = Self::new(name);
        self.children.push(child); // `child` moved here
        child // <-- Error: use of moved value: `child`        
    }

    pub fn add_attribute(&mut self, key: &'a str, value: &'a str) {
        self.attributes.insert(key, value);
    }
}

>Solution :

You can return a mutable reference to the last element:

pub fn add_child(&mut self, name: &'a str) -> &mut Self {
    let mut child = Self::new(name);
    self.children.push(child); // `child` moved here
    self.children.last_mut().unwrap()
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading