rsiot/components_config/influxdb3/
line_protocol_item.rs1use std::collections::HashMap;
2
3use crate::message::*;
4
5use super::FieldValue;
6
7#[derive(Debug)]
9pub struct LineProtocolItem {
10 pub table: String,
12
13 pub tags: HashMap<String, String>,
15
16 pub fields: HashMap<String, FieldValue>,
18
19 pub ts: Option<Timestamp>,
21}
22
23impl LineProtocolItem {
24 pub fn new_simple(table: &str, value: impl Into<FieldValue>) -> Self {
26 Self {
27 table: table.into(),
28 tags: HashMap::new(),
29 fields: HashMap::from([("value".to_string(), value.into())]),
30 ts: Some(Timestamp::default()),
31 }
32 }
33
34 pub fn to_string(&self) -> Result<String, super::Error> {
36 let mut line = String::from("");
37
38 let table = &self.table;
39 line.push_str(table);
40
41 let tags = self
42 .tags
43 .iter()
44 .map(|(k, v)| format!("{k}={v}"))
45 .collect::<Vec<String>>()
46 .join(",");
47 if !tags.is_empty() {
48 line.push(',');
49 line.push_str(&tags);
50 }
51
52 let fields = self
53 .fields
54 .iter()
55 .map(|(k, v)| format!("{k}={v}"))
56 .collect::<Vec<String>>()
57 .join(",");
58 line.push(' ');
59 line.push_str(&fields);
60
61 if let Some(ts) = &self.ts {
62 let ts = ts
63 .timestamp_nanos_opt()
64 .ok_or(super::Error::WrongTimestamp(ts.clone()))?;
65 line.push(' ');
66 line.push_str(&ts.to_string());
67 }
68
69 Ok(line)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use itertools::Itertools;
76
77 use super::*;
78
79 #[test]
81 fn test1() {
82 let lpi = LineProtocolItem {
83 table: "cpu".to_string(),
84 tags: HashMap::from([
85 ("host".to_string(), "Alpha".to_string()),
86 ("region".to_string(), "us-west".to_string()),
87 ("application".to_string(), "webserver".to_string()),
88 ]),
89 fields: HashMap::from([
90 ("val".to_string(), FieldValue::from(1)),
91 ("usage_percent".to_string(), FieldValue::from(20.5)),
92 ("status".to_string(), FieldValue::from("OK".to_string())),
93 ]),
94 ts: None,
95 };
96
97 let lpi: String = lpi.to_string().unwrap();
98
99 println!("line protocol: {}", lpi);
100
101 let from_manual = r#"cpu,host=Alpha,region=us-west,application=webserver val=1i,usage_percent=20.5,status="OK""#;
102 println!("from manual: {}", from_manual);
103
104 assert_eq!(
105 lpi.chars().sorted().rev().collect::<String>(),
106 from_manual.chars().sorted().rev().collect::<String>()
107 );
108 }
109}