axcp/
telemetry.rs

1//! Telemetry functionality for the AXCP SDK.
2
3use crate::client::Client;
4use crate::error::Result;
5use crate::models::TelemetryData;
6use std::collections::HashMap;
7use std::time::{SystemTime, UNIX_EPOCH};
8
9/// A builder for creating telemetry data points.
10#[derive(Debug, Default)]
11pub struct TelemetryBuilder {
12    metric: String,
13    value: f64,
14    tags: HashMap<String, String>,
15    timestamp: Option<i64>,
16}
17
18impl TelemetryBuilder {
19    /// Creates a new telemetry builder with the given metric name and value.
20    pub fn new(metric: impl Into<String>, value: f64) -> Self {
21        Self {
22            metric: metric.into(),
23            value,
24            ..Default::default()
25        }
26    }
27
28    /// Adds a tag to the telemetry data.
29    pub fn with_tag(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
30        self.tags.insert(key.into(), value.into());
31        self
32    }
33
34    /// Sets the timestamp of the telemetry data.
35    pub fn with_timestamp(mut self, timestamp: i64) -> Self {
36        self.timestamp = Some(timestamp);
37        self
38    }
39
40    /// Builds the telemetry data point.
41    pub fn build(self) -> TelemetryData {
42        TelemetryData {
43            metric: self.metric,
44            value: self.value,
45            tags: self.tags,
46            timestamp: self.timestamp.or_else(|| {
47                SystemTime::now()
48                    .duration_since(UNIX_EPOCH)
49                    .ok()
50                    .map(|d| d.as_millis() as i64)
51            }),
52        }
53    }
54}
55
56/// A telemetry client for recording metrics.
57#[derive(Debug, Clone)]
58pub struct TelemetryClient {
59    client: Client,
60}
61
62impl TelemetryClient {
63    /// Creates a new telemetry client.
64    pub fn new(client: Client) -> Self {
65        Self { client }
66    }
67
68    /// Records a metric with the given name and value.
69    pub async fn record_metric(
70        &self,
71        metric: impl Into<String>,
72        value: f64,
73    ) -> Result<()> {
74        let data = TelemetryBuilder::new(metric, value).build();
75        self.client.telemetry().record(data).await
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_telemetry_builder() {
85        let data = TelemetryBuilder::new("test.metric", 42.0)
86            .with_tag("tag1", "value1")
87            .with_tag("tag2", "value2")
88            .with_timestamp(1234567890)
89            .build();
90
91        assert_eq!(data.metric, "test.metric");
92        assert_eq!(data.value, 42.0);
93        assert_eq!(data.tags.get("tag1"), Some(&"value1".to_string()));
94        assert_eq!(data.tags.get("tag2"), Some(&"value2".to_string()));
95        assert_eq!(data.timestamp, Some(1234567890));
96    }
97}