datalogic_rs/builder/
datetime_builder.rs

1use crate::arena::DataArena;
2use crate::logic::{DateTimeOp, Logic, OperatorType};
3use crate::value::DataValue;
4
5/// Builder for datetime operations.
6///
7/// This builder provides a fluent interface for creating datetime operations
8/// such as current time, date formatting, parsing, etc.
9pub struct DateTimeBuilder<'a> {
10    /// The arena in which all allocations will be made.
11    arena: &'a DataArena,
12}
13
14impl<'a> DateTimeBuilder<'a> {
15    /// Creates a new datetime builder.
16    pub fn new(arena: &'a DataArena) -> Self {
17        Self { arena }
18    }
19
20    /// Creates a now operation that returns the current date and time.
21    pub fn now_op(&self) -> Logic<'a> {
22        Logic::operator(
23            OperatorType::DateTime(DateTimeOp::Now),
24            Vec::new(),
25            self.arena,
26        )
27    }
28
29    /// Creates a parse_date operation that parses a date string according to a format.
30    pub fn parse_date_op<S, F>(&self, date_str: S, format: F) -> Logic<'a>
31    where
32        S: Into<Logic<'a>>,
33        F: Into<Logic<'a>>,
34    {
35        Logic::operator(
36            OperatorType::DateTime(DateTimeOp::ParseDate),
37            vec![date_str.into(), format.into()],
38            self.arena,
39        )
40    }
41
42    /// Creates a parse_date operation with string literals.
43    pub fn parse_date(&self, date_str: &str, format: &str) -> Logic<'a> {
44        self.parse_date_op(
45            Logic::literal(DataValue::string(self.arena, date_str), self.arena),
46            Logic::literal(DataValue::string(self.arena, format), self.arena),
47        )
48    }
49
50    /// Creates a format_date operation that formats a date according to a format string.
51    pub fn format_date_op<D, F>(&self, date: D, format: F) -> Logic<'a>
52    where
53        D: Into<Logic<'a>>,
54        F: Into<Logic<'a>>,
55    {
56        Logic::operator(
57            OperatorType::DateTime(DateTimeOp::FormatDate),
58            vec![date.into(), format.into()],
59            self.arena,
60        )
61    }
62
63    /// Creates a date_diff operation that calculates the difference between two dates.
64    pub fn date_diff_op<D1, D2, U>(&self, date1: D1, date2: D2, unit: U) -> Logic<'a>
65    where
66        D1: Into<Logic<'a>>,
67        D2: Into<Logic<'a>>,
68        U: Into<Logic<'a>>,
69    {
70        Logic::operator(
71            OperatorType::DateTime(DateTimeOp::DateDiff),
72            vec![date1.into(), date2.into(), unit.into()],
73            self.arena,
74        )
75    }
76
77    /// Creates a date_diff operation with string unit.
78    pub fn date_diff<D1, D2>(&self, date1: D1, date2: D2, unit: &str) -> Logic<'a>
79    where
80        D1: Into<Logic<'a>>,
81        D2: Into<Logic<'a>>,
82    {
83        self.date_diff_op(
84            date1.into(),
85            date2.into(),
86            Logic::literal(DataValue::string(self.arena, unit), self.arena),
87        )
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94
95    #[test]
96    fn test_datetime_builders() {
97        let arena = DataArena::new();
98        let builder = DateTimeBuilder::new(&arena);
99
100        // Test now operation
101        let now_op = builder.now_op();
102        assert!(matches!(
103            now_op.root().as_operator().unwrap().0,
104            OperatorType::DateTime(DateTimeOp::Now)
105        ));
106
107        // Test parse_date
108        let parse_date = builder.parse_date("2022-07-06", "yyyy-MM-dd");
109        assert!(matches!(
110            parse_date.root().as_operator().unwrap().0,
111            OperatorType::DateTime(DateTimeOp::ParseDate)
112        ));
113
114        // Test date_diff
115        let date_diff = builder.date_diff(
116            Logic::variable("date1", None, &arena),
117            Logic::variable("date2", None, &arena),
118            "days",
119        );
120        assert!(matches!(
121            date_diff.root().as_operator().unwrap().0,
122            OperatorType::DateTime(DateTimeOp::DateDiff)
123        ));
124    }
125}