rrdcached_client/
batch_update.rs

1use crate::{errors::RRDCachedClientError, now::now_timestamp, sanitisation::check_rrd_path};
2
3pub struct BatchUpdate {
4    path: String,
5    timestamp: Option<usize>,
6    data: Vec<f64>,
7}
8
9impl BatchUpdate {
10    pub fn new(
11        path: &str,
12        timestamp: Option<usize>,
13        data: Vec<f64>,
14    ) -> Result<BatchUpdate, RRDCachedClientError> {
15        if data.is_empty() {
16            return Err(RRDCachedClientError::InvalidBatchUpdate(
17                "data is empty".to_string(),
18            ));
19        }
20        check_rrd_path(path)?;
21        Ok(BatchUpdate {
22            path: path.to_string(),
23            timestamp,
24            data,
25        })
26    }
27
28    pub fn to_command_string(&self) -> Result<String, RRDCachedClientError> {
29        let timestamp_str = match self.timestamp {
30            Some(ts) => ts.to_string(),
31            None => now_timestamp()?.to_string(),
32        };
33        let data_str = self
34            .data
35            .iter()
36            .map(|f| f.to_string())
37            .collect::<Vec<String>>()
38            .join(":");
39        let mut command = String::with_capacity(
40            7 + self.path.len() + 5 + timestamp_str.len() + 1 + data_str.len() + 1,
41        );
42        command.push_str("UPDATE ");
43        command.push_str(&self.path);
44        command.push_str(".rrd ");
45        command.push_str(&timestamp_str);
46        command.push(':');
47        command.push_str(&data_str);
48        command.push('\n');
49
50        Ok(command)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_new_with_valid_data() {
60        let path = "valid_path";
61        let timestamp = Some(123456789);
62        let data = vec![1.0, 2.0, 3.0];
63        let batch_update = BatchUpdate::new(path, timestamp, data).unwrap();
64        assert_eq!(batch_update.path, "valid_path");
65        assert_eq!(batch_update.timestamp, Some(123456789));
66        assert_eq!(batch_update.data, vec![1.0, 2.0, 3.0]);
67    }
68
69    #[test]
70    fn test_new_with_empty_data() {
71        let path = "valid_path";
72        let timestamp = Some(123456789);
73        let data = vec![];
74        let result = BatchUpdate::new(path, timestamp, data);
75        assert!(matches!(
76            result,
77            Err(RRDCachedClientError::InvalidBatchUpdate(msg)) if msg == "data is empty"
78        ));
79    }
80
81    #[test]
82    fn test_to_command_string_with_timestamp() {
83        let batch_update = BatchUpdate {
84            path: "test_path".into(),
85            timestamp: Some(1609459200), // Example timestamp
86            data: vec![1.1, 2.2, 3.3],
87        };
88        let command = batch_update.to_command_string().unwrap();
89        assert_eq!(command, "UPDATE test_path.rrd 1609459200:1.1:2.2:3.3\n");
90    }
91}