Skip to content

Commit 35a918d

Browse files
committed
Improved Typesafety and Error Handling
1 parent 82b1374 commit 35a918d

File tree

3 files changed

+78
-43
lines changed

3 files changed

+78
-43
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ reqwest = "0.9.17"
1111
futures = "0.1.27"
1212
tokio = "0.1.20"
1313
itertools = "0.8"
14+
failure = "0.1.5"

src/main.rs

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,47 @@
11
#![allow(dead_code)]
22

3+
#[macro_use]
4+
extern crate failure;
5+
36
use futures::Future;
47
use itertools::Itertools;
58
use reqwest::r#async::Client;
69

10+
#[derive(Debug, Fail)]
11+
enum InfluxDbError {
12+
#[fail(display = "query must contain at least one field")]
13+
InvalidQueryError,
14+
}
15+
16+
#[derive(Debug)]
17+
struct ValidQuery(String);
18+
impl From<String> for ValidQuery {
19+
fn from(s: String) -> ValidQuery {
20+
ValidQuery(s)
21+
}
22+
}
23+
impl PartialEq<String> for ValidQuery {
24+
fn eq(&self, other: &String) -> bool {
25+
&self.0 == other
26+
}
27+
}
28+
impl PartialEq<&str> for ValidQuery {
29+
fn eq(&self, other: &&str) -> bool {
30+
&self.0 == other
31+
}
32+
}
33+
734
trait InfluxDbQuery {
8-
fn build<'a>(self) -> String;
35+
fn build<'a>(self) -> Result<ValidQuery, InfluxDbError>;
936
}
1037

1138
impl InfluxDbQuery {
12-
pub fn write() -> InfluxDbWrite {
39+
pub fn write<S>(measurement: S) -> InfluxDbWrite
40+
where
41+
S: Into<String>,
42+
{
1343
InfluxDbWrite {
14-
measurement: String::from("marina_3"),
44+
measurement: measurement.into(),
1545
fields: Vec::new(),
1646
tags: Vec::new(),
1747
}
@@ -45,32 +75,40 @@ impl InfluxDbWrite {
4575
}
4676
}
4777

78+
// todo: fuse_with(other: ValidQuery), so multiple queries can be run at the same time
4879
impl InfluxDbQuery for InfluxDbWrite {
4980
// fixme: time (with precision) and measurement
50-
fn build<'a>(self) -> String {
81+
fn build<'a>(self) -> Result<ValidQuery, InfluxDbError> {
82+
if self.fields.is_empty() {
83+
return Err(InfluxDbError::InvalidQueryError);
84+
}
85+
5186
let tags = self
5287
.tags
5388
.into_iter()
5489
.map(|(tag, value)| format!("{tag}={value}", tag = tag, value = value))
55-
.join(",");
90+
.join(",")
91+
+ " ";
5692
let fields = self
5793
.fields
5894
.into_iter()
5995
.map(|(field, value)| format!("{field}={value}", field = field, value = value))
60-
.join(",");
96+
.join(",")
97+
+ " ";
6198

62-
format!(
63-
"measurement,{tags} {fields} time",
99+
Ok(ValidQuery::from(format!(
100+
"{measurement},{tags}{fields}time",
101+
measurement = self.measurement,
64102
tags = tags,
65103
fields = fields
66-
)
104+
)))
67105
}
68106
}
69107

70108
pub struct InfluxDbClient {
71109
url: String,
72110
database: String,
73-
// _auth: InfluxDbAuthentication | NoAuthentication
111+
// auth: Option<InfluxDbAuthentication>
74112
}
75113

76114
pub fn main() {}
@@ -129,67 +167,62 @@ mod tests {
129167
println!("build: {} version: {}", build, version);
130168
}
131169

170+
#[test]
171+
fn test_write_builder_empty_query() {
172+
let query = InfluxDbQuery::write("marina_3").build();
173+
174+
assert!(query.is_err(), "Query was not empty");
175+
}
176+
132177
#[test]
133178
fn test_write_builder_single_field() {
134-
let query = InfluxDbQuery::write().add_field("water_level", "2");
179+
let query = InfluxDbQuery::write("marina_3")
180+
.add_field("water_level", "2")
181+
.build();
135182

136-
assert_eq!(query.build(), "measurement, water_level=2 time");
183+
assert!(query.is_ok(), "Query was empty");
184+
assert_eq!(query.unwrap(), "marina_3, water_level=2 time");
137185
}
138186

139187
#[test]
140188
fn test_write_builder_multiple_fields() {
141-
let query = InfluxDbQuery::write()
189+
let query = InfluxDbQuery::write("marina_3")
142190
.add_field("water_level", "2")
143191
.add_field("boat_count", "31")
144-
.add_field("algae_content", "0.85");
192+
.add_field("algae_content", "0.85")
193+
.build();
145194

195+
assert!(query.is_ok(), "Query was empty");
146196
assert_eq!(
147-
query.build(),
148-
"measurement, water_level=2,boat_count=31,algae_content=0.85 time"
197+
query.unwrap(),
198+
"marina_3, water_level=2,boat_count=31,algae_content=0.85 time"
149199
);
150200
}
151201

152-
// fixme: double space
153202
// fixme: quoting / escaping of long strings
154203
#[test]
155-
fn test_write_builder_single_tag() {
156-
let query = InfluxDbQuery::write().add_tag("marina_manager", "Smith");
157-
158-
assert_eq!(query.build(), "measurement,marina_manager=Smith time");
159-
}
160-
161-
#[test]
162-
fn test_write_builder_multiple_tags() {
163-
let query = InfluxDbQuery::write()
204+
fn test_write_builder_only_tags() {
205+
let query = InfluxDbQuery::write("marina_3")
164206
.add_tag("marina_manager", "Smith")
165-
.add_tag("manager_to_the_marina_manager", "Jonson");
207+
.build();
166208

167-
assert_eq!(
168-
query.build(),
169-
"measurement,marina_manager=Smith,manager_to_the_marina_manager=Jonson time"
170-
);
209+
assert!(query.is_err(), "Query missing one or more fields");
171210
}
172211

173212
#[test]
174213
fn test_write_builder_full_query() {
175-
let query = InfluxDbQuery::write()
214+
let query = InfluxDbQuery::write("marina_3")
176215
.add_field("water_level", "2")
177216
.add_field("boat_count", "31")
178217
.add_field("algae_content", "0.85")
179218
.add_tag("marina_manager", "Smith")
180-
.add_tag("manager_to_the_marina_manager", "Jonson");
219+
.add_tag("manager_to_the_marina_manager", "Jonson")
220+
.build();
181221

222+
assert!(query.is_ok(), "Query was empty");
182223
assert_eq!(
183-
query.build(),
184-
"measurement,marina_manager=Smith,manager_to_the_marina_manager=Jonson water_level=2,boat_count=31,algae_content=0.85 time"
224+
query.unwrap(),
225+
"marina_3,marina_manager=Smith,manager_to_the_marina_manager=Jonson water_level=2,boat_count=31,algae_content=0.85 time"
185226
);
186227
}
187-
188-
#[test]
189-
fn test_test() {
190-
InfluxDbQuery::write()
191-
.add_field("test", "1")
192-
.add_tag("my_tag", "0.85")
193-
.build();
194-
}
195228
}

0 commit comments

Comments
 (0)