Mathieu David
Mathieu David

Reputation: 5268

&self move field containing Box - Move out of borrowed content

I have a struct with a field containing references to other structs (that I did not define)

struct HtmlHandlebars {
    user_helpers: Vec<(String, Box<HelperDef + 'static>)>,
}

And HtmlHandlebars has to implement a function

fn render(&self, ...) -> &self

And in that function I would need to move the Box to another function. Something like this:

fn render(&self, ...) -> &self {
    let mut handlebars = Handlebars::new();
    for (name, helper) in self.user_helpers {
        handlebars.register_helper(&name, helper);
    }
}

But I am kind of stuck because:

Maybe I am doing it completely wrong.. Is there something else I can do? What are my options?

If you need a more complete overview of the code, you can find it here

PS: I had no idea how to describe the situation in the title, feel free to change it

Upvotes: 1

Views: 219

Answers (1)

user395760
user395760

Reputation:

The code you've written is trying to consume the Vec and its elements. In general, you can iterate over &self.user_helpers which will give you references to the elements rather than consuming them. That is (modulo silly typos in the pattern):

for &(ref name, ref helper) in self.user_helpers {
    handlebars.register_helper(name, helper);
}

See also: The Rust Programming Language on iterating vectors.

There is a problem with that though: Handlebars needs ownership of the helpers. It may very well be that you have to create a new Handlebars object every time you render, but in that case you also need to be able to create all the helpers every time you create a new Handlebars. There is no way to take ownership of the boxes without taking at least a &mut reference to the Vec. You need at least mutable access to take the handlers out of the struct. And if you did that, you wouldn't have the handlers around for the next time render() is called. Depending on how configurable the set of handlers is, you could have a function that constructs the Vec<Box<HelperDef + 'static>> out of thin air when you need it, or you could maintain a list of callbacks that construct Box<HelperDef + 'static> for you.

Upvotes: 1

Related Questions