1use crate::client::Client;
4use crate::error::Result;
5use crate::models::TelemetryData;
6use std::collections::HashMap;
7use std::time::{SystemTime, UNIX_EPOCH};
8
9#[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 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 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 pub fn with_timestamp(mut self, timestamp: i64) -> Self {
36 self.timestamp = Some(timestamp);
37 self
38 }
39
40 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#[derive(Debug, Clone)]
58pub struct TelemetryClient {
59 client: Client,
60}
61
62impl TelemetryClient {
63 pub fn new(client: Client) -> Self {
65 Self { client }
66 }
67
68 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}