rsiot/components_config/influxdb3/
line_protocol_item.rs1use std::collections::HashMap;
2
3use crate::message::*;
4
5use super::FieldValue;
6
7#[derive(Debug)]
10pub struct LineProtocolItem {
11 pub table: String,
13
14 pub tags: HashMap<String, String>,
16
17 pub fields: HashMap<String, FieldValue>,
19
20 pub ts: Option<Timestamp>,
22}
23impl LineProtocolItem {
26 pub fn new_simple(table: &str, value: impl Into<FieldValue>) -> Self {
28 Self {
29 table: table.into(),
30 tags: HashMap::new(),
31 fields: HashMap::from([("value".to_string(), value.into())]),
32 ts: Some(Timestamp::default()),
33 }
34 }
35
36 pub fn to_string(&self) -> Result<String, super::Error> {
38 let mut line = String::from("");
39
40 let table = &self.table;
41 line.push_str(table);
42
43 let tags = self
44 .tags
45 .iter()
46 .map(|(k, v)| format!("{k}={v}"))
47 .collect::<Vec<String>>()
48 .join(",");
49 if !tags.is_empty() {
50 line.push(',');
51 line.push_str(&tags);
52 }
53
54 let fields = self
55 .fields
56 .iter()
57 .map(|(k, v)| format!("{k}={v}"))
58 .collect::<Vec<String>>()
59 .join(",");
60 line.push(' ');
61 line.push_str(&fields);
62
63 if let Some(ts) = &self.ts {
64 let ts = ts.unix_timestamp_nanos();
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() -> anyhow::Result<()> {
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()?;
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 Ok(())
110 }
111}