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?
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);
}
}
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()
}