[Rust] Handle lifetimes with Traits in Tera

The reason Zola is using so much memory is that the Tera functions get_page/get_section/get_taxonomy clone all the pages/sections to be able to use them in templates.

The next version of Tera (1.0.0) will turn function/filters/tests into traits rather then Fn types. For example the global function trait is:

/// The global function type definition
pub trait Function: Sync + Send {
    /// The global function type definition
    fn call(&self, args: &HashMap<String, Value>) -> Result<Value>;
}

That’s nicer than a user POV but we still need to clone everything.
My thoughts were to have a lifetime referencing the Tera instance that binds the traits like so:

pub struct Tera<'tera> {
    #[doc(hidden)]
    pub functions: HashMap<String, Arc<dyn Function + 'tera>>,
}

I made an example of what should be working ideally: https://github.com/Keats/tera/blob/lifetime-issue/examples/borrowed_trait_context/main.rs but you end up having lifetime issues all around.

Does anyone has a good idea on that before I ask on users.rustlang?

1 Like