1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use std::fmt;
use std::io::Write;
use itertools;
use super::Filter;
use liquid_error::{Result, ResultLiquidExt, ResultLiquidReplaceExt};
use liquid_interpreter::Expression;
use liquid_interpreter::Renderable;
use liquid_interpreter::Runtime;
use liquid_value::{ValueCow, ValueView};
#[derive(Debug)]
pub struct FilterChain {
entry: Expression,
filters: Vec<Box<dyn Filter>>,
}
impl FilterChain {
pub fn new(entry: Expression, filters: Vec<Box<dyn Filter>>) -> Self {
Self { entry, filters }
}
pub fn evaluate<'s>(&'s self, runtime: &'s Runtime) -> Result<ValueCow<'s>> {
let mut entry = self.entry.evaluate(runtime)?;
for filter in &self.filters {
entry = ValueCow::Owned(
filter
.evaluate(entry.as_view(), runtime)
.trace("Filter error")
.context_key("filter")
.value_with(|| format!("{}", filter).into())
.context_key("input")
.value_with(|| format!("{}", entry.source()).into())?,
);
}
Ok(entry)
}
}
impl fmt::Display for FilterChain {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{} | {}",
self.entry,
itertools::join(&self.filters, " | ")
)
}
}
impl Renderable for FilterChain {
fn render_to(&self, writer: &mut dyn Write, runtime: &mut Runtime) -> Result<()> {
let entry = self.evaluate(runtime)?;
write!(writer, "{}", entry.render()).replace("Failed to render")?;
Ok(())
}
}