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
66
67
68
69
70
71
72
73
74
75
76
77
78
use chrono::Duration;
use minijinja::{value::Value, Error, ErrorKind};
use std::time::SystemTime;

use super::values::UtcDateTimeValue;
use crate::events::UtcDateTime;

/// create a date using the current date time
pub fn now() -> Value {
    Value::from_object(UtcDateTimeValue::new(UtcDateTime::from(SystemTime::now())))
}

/// create a date in the future add `days`, `weeks`, `hours`, `mins`, `secs` (or any combinations of them) to create
/// a date in the future. Example:
/// ```no_compile
///     {{ future(weeks=3, days=4, hours=20, mins=10)}}
/// ```
pub fn future(kwargs: Value) -> Result<Value, Error> {
    let date = UtcDateTime::from(SystemTime::now());
    let mut duration = Duration::zero();
    if let Some(Ok(days)) = kwargs
        .get_attr("days")
        .ok()
        .filter(|x| !x.is_undefined())
        .and_then(|f| f.as_str().map(str::parse::<i64>))
    {
        duration = duration
            .checked_add(&Duration::days(days))
            .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "days couldn’t be added"))?;
    }

    if let Some(Ok(weeks)) = kwargs
        .get_attr("weeks")
        .ok()
        .filter(|x| !x.is_undefined())
        .and_then(|f| f.as_str().map(str::parse::<i64>))
    {
        duration = duration
            .checked_add(&Duration::weeks(weeks))
            .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "weeks couldn’t be added"))?;
    }

    if let Some(Ok(hours)) = kwargs
        .get_attr("hours")
        .ok()
        .filter(|x| !x.is_undefined())
        .and_then(|f| f.as_str().map(str::parse::<i64>))
    {
        duration = duration
            .checked_add(&Duration::hours(hours))
            .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "hours couldn’t be added"))?;
    }

    if let Some(Ok(minutes)) = kwargs
        .get_attr("mins")
        .ok()
        .filter(|x| !x.is_undefined())
        .and_then(|f| f.as_str().map(str::parse::<i64>))
    {
        duration = duration
            .checked_add(&Duration::minutes(minutes))
            .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "minutes couldn’t be added"))?;
    }

    if let Some(Ok(seconds)) = kwargs
        .get_attr("secs")
        .ok()
        .filter(|x| !x.is_undefined())
        .and_then(|f| f.as_str().map(str::parse::<i64>))
    {
        duration = duration
            .checked_add(&Duration::seconds(seconds))
            .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "seconds couldn’t be added"))?;
    }

    let val = Value::from_object(UtcDateTimeValue::new(date + duration));
    Ok(val)
}