rinfluxdb_lineprotocol/line_builder.rs
1// Copyright Claudio Mattera 2021.
2// Distributed under the MIT License or Apache 2.0 License at your option.
3// See accompanying files License-MIT.txt and License-Apache-2.0, or online at
4// https://opensource.org/licenses/MIT
5// https://opensource.org/licenses/Apache-2.0
6
7use ::chrono::{DateTime, Utc};
8
9use super::FieldName;
10use super::FieldValue;
11use super::Line;
12use super::Measurement;
13use super::TagName;
14use super::TagValue;
15
16/// Build a record
17#[derive(Clone, Debug, PartialEq)]
18pub struct LineBuilder {
19 line: Line,
20}
21
22impl LineBuilder {
23 /// Create a new line for a measurement
24 ///
25 /// ```
26 /// # use rinfluxdb_lineprotocol::LineBuilder;
27 /// let line = LineBuilder::new("measurement")
28 /// .build();
29 /// assert_eq!(line.measurement(), &"measurement".into());
30 /// ```
31 pub fn new(measurement: impl Into<Measurement>) -> Self {
32 Self {
33 line: Line::new(measurement),
34 }
35 }
36
37 /// Insert a field in the line
38 ///
39 /// ```
40 /// # use rinfluxdb_lineprotocol::LineBuilder;
41 /// let line = LineBuilder::new("measurement")
42 /// .insert_field("latitude", 55.383333)
43 /// .insert_field("longitude", 10.383333)
44 /// .build();
45 /// assert_eq!(line.field("latitude"), Some(&55.383333.into()));
46 /// assert_eq!(line.field("longitude"), Some(&10.383333.into()));
47 /// ```
48 pub fn insert_field(self, name: impl Into<FieldName>, value: impl Into<FieldValue>) -> Self {
49 let mut line = self.line;
50 line.insert_field(name, value);
51 Self { line }
52 }
53
54 /// Insert a tag in the line
55 ///
56 /// ```
57 /// # use rinfluxdb_lineprotocol::LineBuilder;
58 /// let line = LineBuilder::new("measurement")
59 /// .insert_tag("city", "Odense")
60 /// .build();
61 /// assert_eq!(line.tag("city"), Some(&"Odense".into()));
62 /// ```
63 pub fn insert_tag(self, name: impl Into<TagName>, value: impl Into<TagValue>) -> Self {
64 let mut line = self.line;
65 line.insert_tag(name, value);
66 Self { line }
67 }
68
69 /// Set the line timestamp
70 ///
71 /// ```
72 /// # use rinfluxdb_lineprotocol::LineBuilder;
73 /// # use chrono::{TimeZone, Utc};
74 /// let line = LineBuilder::new("measurement")
75 /// .set_timestamp(Utc.ymd(2014, 7, 8).and_hms(9, 10, 11))
76 /// .build();
77 /// assert_eq!(line.timestamp(), Some(&Utc.ymd(2014, 7, 8).and_hms(9, 10, 11)));
78 /// ```
79 pub fn set_timestamp(self, timestamp: DateTime<Utc>) -> Self {
80 let mut line = self.line;
81 line.set_timestamp(timestamp);
82 Self { line }
83 }
84
85 /// Build the line
86 ///
87 /// ```
88 /// # use rinfluxdb_lineprotocol::LineBuilder;
89 /// # use chrono::{TimeZone, Utc};
90 /// let line = LineBuilder::new("measurement")
91 /// .insert_field("latitude", 55.383333)
92 /// .insert_field("longitude", 10.383333)
93 /// .insert_tag("city", "Odense")
94 /// .set_timestamp(Utc.ymd(2014, 7, 8).and_hms(9, 10, 11))
95 /// .build();
96 /// assert_eq!(line.measurement(), &"measurement".into());
97 /// assert_eq!(line.field("latitude"), Some(&55.383333.into()));
98 /// assert_eq!(line.field("longitude"), Some(&10.383333.into()));
99 /// assert_eq!(line.tag("city"), Some(&"Odense".into()));
100 /// assert_eq!(line.timestamp(), Some(&Utc.ymd(2014, 7, 8).and_hms(9, 10, 11)));
101 /// ```
102 pub fn build(self) -> Line {
103 self.line
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 use chrono::TimeZone;
112
113 #[test]
114 fn create_record() {
115 let actual = LineBuilder::new("location")
116 .insert_tag("city", "Odense")
117 .insert_field("latitude", FieldValue::Float(55.383333))
118 .insert_field("longitude", FieldValue::Float(10.383333))
119 .set_timestamp(Utc.ymd(2014, 7, 8).and_hms(9, 10, 11))
120 .build();
121
122 let mut expected = Line::new("location");
123 expected.insert_tag("city", "Odense");
124 expected.insert_field("latitude", FieldValue::Float(55.383333));
125 expected.insert_field("longitude", FieldValue::Float(10.383333));
126 expected.set_timestamp(Utc.ymd(2014, 7, 8).and_hms(9, 10, 11));
127
128 assert_eq!(actual, expected);
129 }
130}