dsq_functions/builtin/
date_diff.rs

1use dsq_shared::value::Value;
2use dsq_shared::Result;
3use inventory;
4
5pub fn builtin_date_diff(args: &[Value]) -> Result<Value> {
6    if args.len() != 2 {
7        return Err(dsq_shared::error::operation_error(
8            "date_diff() expects 2 arguments",
9        ));
10    }
11
12    match (&args[0], &args[1]) {
13        (Value::Array(arr1), Value::Array(arr2)) => {
14            if arr1.len() != arr2.len() {
15                return Err(dsq_shared::error::operation_error(
16                    "date_diff() arrays must have same length",
17                ));
18            }
19            let mut results = Vec::new();
20            for (v1, v2) in arr1.iter().zip(arr2.iter()) {
21                let dt1 = crate::extract_timestamp(v1)?;
22                let dt2 = crate::extract_timestamp(v2)?;
23                let duration = (dt1 - dt2).abs();
24                results.push(Value::Int(duration.num_days() as i64));
25            }
26            Ok(Value::Array(results))
27        }
28        _ => {
29            let dt1 = crate::extract_timestamp(&args[0])?;
30            let dt2 = crate::extract_timestamp(&args[1])?;
31            let duration = (dt1 - dt2).abs();
32            Ok(Value::Int(duration.num_days() as i64))
33        }
34    }
35}
36
37inventory::submit! {
38    crate::FunctionRegistration {
39        name: "date_diff",
40        func: builtin_date_diff,
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use dsq_shared::value::Value;
48
49    #[test]
50    fn test_date_diff_function() {
51        // Test with date strings
52        let result = builtin_date_diff(&[
53            Value::String("2023-01-01".to_string()),
54            Value::String("2023-01-05".to_string()),
55        ])
56        .unwrap();
57        assert_eq!(result, Value::Int(4));
58
59        // Test with same date
60        let result = builtin_date_diff(&[
61            Value::String("2023-01-01".to_string()),
62            Value::String("2023-01-01".to_string()),
63        ])
64        .unwrap();
65        assert_eq!(result, Value::Int(0));
66
67        // Test with RFC3339 strings
68        let result = builtin_date_diff(&[
69            Value::String("2023-01-01T00:00:00Z".to_string()),
70            Value::String("2023-01-05T00:00:00Z".to_string()),
71        ])
72        .unwrap();
73        assert_eq!(result, Value::Int(4));
74
75        // Test with arrays
76        let arr1 = Value::Array(vec![
77            Value::String("2023-01-01".to_string()),
78            Value::String("2023-02-01".to_string()),
79        ]);
80        let arr2 = Value::Array(vec![
81            Value::String("2023-01-05".to_string()),
82            Value::String("2023-02-05".to_string()),
83        ]);
84        let result = builtin_date_diff(&[arr1, arr2]).unwrap();
85        assert_eq!(result, Value::Array(vec![Value::Int(4), Value::Int(4)]));
86    }
87}