liquid_lib/stdlib/filters/string/
mod.rs

1use liquid_core::Expression;
2use liquid_core::Result;
3use liquid_core::Runtime;
4use liquid_core::{
5    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
6};
7use liquid_core::{Value, ValueView};
8
9pub(super) mod case;
10pub(super) mod operate;
11pub(super) mod strip;
12pub(super) mod truncate;
13
14#[derive(Debug, FilterParameters)]
15struct SplitArgs {
16    #[parameter(
17        description = "The separator between each element in the string.",
18        arg_type = "str"
19    )]
20    pattern: Expression,
21}
22
23#[derive(Clone, ParseFilter, FilterReflection)]
24#[filter(
25    name = "split",
26    description = "Divides an input string into an array using the argument as a separator.",
27    parameters(SplitArgs),
28    parsed(SplitFilter)
29)]
30pub struct Split;
31
32#[derive(Debug, FromFilterParameters, Display_filter)]
33#[name = "split"]
34struct SplitFilter {
35    #[parameters]
36    args: SplitArgs,
37}
38
39impl Filter for SplitFilter {
40    fn evaluate(&self, input: &dyn ValueView, runtime: &dyn Runtime) -> Result<Value> {
41        let args = self.args.evaluate(runtime)?;
42
43        let input = input.to_kstr();
44
45        if input.is_empty() {
46            Ok(Value::Array(Vec::new()))
47        } else {
48            // Split and construct resulting Array
49            Ok(Value::Array(
50                input
51                    .split(args.pattern.as_str())
52                    .map(|s| Value::scalar(s.to_owned()))
53                    .collect(),
54            ))
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn unit_split() {
65        assert_eq!(
66            liquid_core::call_filter!(Split, "a, b, c", ", ").unwrap(),
67            liquid_core::value!(["a", "b", "c"])
68        );
69        assert_eq!(
70            liquid_core::call_filter!(Split, "a~b", "~").unwrap(),
71            liquid_core::value!(["a", "b"])
72        );
73    }
74
75    #[test]
76    fn unit_split_bad_split_string() {
77        assert_eq!(
78            liquid_core::call_filter!(Split, "a,b,c", 1f64).unwrap(),
79            liquid_core::value!(["a,b,c"])
80        );
81    }
82
83    #[test]
84    fn unit_split_no_args() {
85        liquid_core::call_filter!(Split, "a,b,c").unwrap_err();
86    }
87}