Module upon::filters

source ·
Available on crate feature filters only.
Expand description

An abstraction over any filter function or closure.

The Filter trait is used by the Engine::add_filter method to abstract over a variety of function and closure types. This includes filters with variable argument types, return types and arity. The first argument to a filter function will always receive the piped value or expression. It can then have up to four more arguments. The renderer will check the number of arguments and the type of arguments when the filter is used. Generally you should not try to implement any of the traits in this module yourself, instead you should define functions or closures that adhere to the generic implementation provided.

§Types

Filter is implemented for functions and closures that take any owned argument implementing FilterArg and any return type implementing FilterReturn.

Additionally, the first argument to the filter (i.e. the piped expression) can also be specified using the following reference types. This is preferred in most cases because the renderer won’t have to clone the value before passing it to the filter.

Other arguments can also use &str but only if the passed parameter is always a literal string.

§Examples

§Using existing functions

A lot of standard library functions can be used as filters, as long as they have the supported argument and return types.

let mut engine = upon::Engine::new();
engine.add_filter("lower", str::to_lowercase);
engine.add_filter("abs", i64::abs);

§Closures

Closures are perfectly valid filters.

let mut engine = upon::Engine::new();
engine.add_filter("add", |a: i64, b: i64| a + b);

This could be use like this

{{ user.age | add: 10 }}

§Owned vs reference arguments

Consider the following template.

{{ users | last }}

Where the last filter retrieves the final element in a list. We could implement this filter taking an owned argument.

fn last(mut list: Vec<Value>) -> Option<Value> {
    list.pop()
}

But it would be more efficient to implement it such that it takes a slice, because then only the last element is cloned, as opposed to all the elements in the list being cloned.

fn last(list: &[Value]) -> Option<Value> {
    list.last().map(Clone::clone)
}

Traits§