liquid_lib/stdlib/filters/
date.rs

1use liquid_core::Expression;
2use liquid_core::Runtime;
3use liquid_core::{
4    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
5};
6use liquid_core::{Error, Result};
7use liquid_core::{Value, ValueView};
8
9#[derive(Debug, FilterParameters)]
10struct DateArgs {
11    #[parameter(description = "The format to return the date in.", arg_type = "str")]
12    format: Expression,
13}
14
15#[derive(Clone, ParseFilter, FilterReflection)]
16#[filter(
17    name = "date",
18    description = "Converts a timestamp into another date format.",
19    parameters(DateArgs),
20    parsed(DateFilter)
21)]
22pub struct Date;
23
24#[derive(Debug, FromFilterParameters, Display_filter)]
25#[name = "date"]
26struct DateFilter {
27    #[parameters]
28    args: DateArgs,
29}
30
31impl Filter for DateFilter {
32    fn evaluate(&self, input: &dyn ValueView, runtime: &dyn Runtime) -> Result<Value> {
33        let args = self.args.evaluate(runtime)?;
34
35        let date = input.as_scalar().and_then(|s| s.to_date_time());
36        match date {
37            Some(date) if !args.format.is_empty() => {
38                let s = date.format(args.format.as_str()).map_err(|_err| {
39                    Error::with_msg(format!("Invalid date-format string: {}", args.format))
40                })?;
41
42                Ok(Value::scalar(s))
43            }
44            _ => Ok(input.to_value()),
45        }
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn unit_date() {
55        assert_eq!(
56            liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300", "%Y-%m-%d").unwrap(),
57            liquid_core::value!("2016-06-13")
58        );
59    }
60
61    #[test]
62    fn unit_date_invalid_format() {
63        liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300", "%Y %h %8").unwrap_err();
64    }
65
66    #[test]
67    fn unit_date_cobalt_format() {
68        assert_eq!(
69            liquid_core::call_filter!(Date, "2016-06-13 02:30:00 +0300", "%Y-%m-%d").unwrap(),
70            liquid_core::value!("2016-06-13")
71        );
72    }
73
74    #[test]
75    fn unit_date_bad_input_type() {
76        assert_eq!(
77            liquid_core::call_filter!(Date, 0f64, "%Y-%m-%d").unwrap(),
78            Value::scalar(0f64)
79        );
80    }
81
82    #[test]
83    fn unit_date_bad_input_format() {
84        assert_eq!(
85            liquid_core::call_filter!(Date, "blah blah blah", "%Y-%m-%d").unwrap(),
86            liquid_core::value!("blah blah blah")
87        );
88    }
89
90    #[test]
91    fn unit_date_format_empty() {
92        assert_eq!(
93            liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300", "").unwrap(),
94            liquid_core::value!("13 Jun 2016 02:30:00 +0300")
95        );
96    }
97
98    #[test]
99    fn unit_date_bad_format_type() {
100        assert_eq!(
101            liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300", 0f64).unwrap(),
102            liquid_core::value!("0")
103        );
104    }
105
106    #[test]
107    fn unit_date_missing_format() {
108        liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300").unwrap_err();
109    }
110
111    #[test]
112    fn unit_date_extra_param() {
113        liquid_core::call_filter!(Date, "13 Jun 2016 02:30:00 +0300", 0f64, 1f64).unwrap_err();
114    }
115}