Skip to content

Commit 52f33c3

Browse files
committed
refactor away from PhantomData & compile time type check
1 parent 9eb5dc5 commit 52f33c3

File tree

6 files changed

+143
-71
lines changed

6 files changed

+143
-71
lines changed

benches/client.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use chrono::{DateTime, Utc};
22
use influxdb::Error;
33
use influxdb::InfluxDbWriteable;
4-
use influxdb::InfluxVersion1;
54
use influxdb::{Client, ReadQuery};
65
use std::sync::Arc;
76
use std::time::Instant;
@@ -23,7 +22,7 @@ async fn main() {
2322
let number_of_total_requests = 20000;
2423
let concurrent_requests = 1000;
2524

26-
let client: Client<InfluxVersion1> = Client::new(url, db_name);
25+
let client = Client::new(url, db_name);
2726
let concurrency_limit = Arc::new(Semaphore::new(concurrent_requests));
2827

2928
prepare_influxdb(&client, db_name).await;
@@ -65,7 +64,7 @@ async fn main() {
6564
);
6665
}
6766

68-
async fn prepare_influxdb<V>(client: &Client<V>, db_name: &str) {
67+
async fn prepare_influxdb(client: &Client, db_name: &str) {
6968
let create_db_stmt = format!("CREATE DATABASE {}", db_name);
7069
client
7170
.query(&ReadQuery::new(create_db_stmt))

influxdb/src/client/mod.rs

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,28 @@ use futures_util::TryFutureExt;
1919
use reqwest::{Client as HttpClient, RequestBuilder, Response as HttpResponse};
2020
use std::collections::{BTreeMap, HashMap};
2121
use std::fmt::{self, Debug, Formatter};
22-
use std::marker::PhantomData;
2322
use std::sync::Arc;
2423

2524
use crate::query::QueryType;
2625
use crate::Error;
2726
use crate::Query;
2827

29-
/// Marker type for InfluxDB Version 1
30-
#[derive(Clone)]
31-
pub struct InfluxVersion1;
32-
/// Marker type for InfluxDB Version 2
33-
#[derive(Clone)]
34-
pub struct InfluxVersion2;
35-
/// Marker type for InfluxDB Version 3
36-
#[derive(Clone)]
37-
pub struct InfluxVersion3;
28+
#[derive(Clone, Debug, PartialEq, Eq)]
29+
#[non_exhaustive]
30+
pub enum InfluxDbVersion {
31+
V1,
32+
V2,
33+
V3,
34+
}
3835

3936
#[derive(Clone)]
4037
/// Internal Representation of a Client
41-
pub struct Client<V, H = reqwest::Client> {
38+
pub struct Client<H = reqwest::Client> {
4239
pub(crate) url: Arc<String>,
4340
pub(crate) parameters: Arc<HashMap<&'static str, String>>,
4441
pub(crate) token: Option<String>,
4542
pub(crate) client: H,
46-
_version: PhantomData<V>,
43+
pub(crate) version: InfluxDbVersion,
4744
}
4845

4946
struct RedactPassword<'a>(&'a HashMap<&'static str, String>);
@@ -62,17 +59,18 @@ impl<'a> Debug for RedactPassword<'a> {
6259
}
6360
}
6461

65-
impl<V, H> Debug for Client<V, H> {
62+
impl<H> Debug for Client<H> {
6663
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
6764
f.debug_struct("Client")
6865
.field("url", &self.url)
6966
.field("parameters", &RedactPassword(&self.parameters))
67+
.field("version", &self.version)
7068
.finish_non_exhaustive()
7169
}
7270
}
7371

74-
impl<V> Client<V, reqwest::Client> {
75-
/// Instantiates a new [`Client`](crate::Client)
72+
impl Client<reqwest::Client> {
73+
/// Instantiates a new [`Client`](crate::Client) for InfluxDB v1.
7674
///
7775
/// # Arguments
7876
///
@@ -94,12 +92,78 @@ impl<V> Client<V, reqwest::Client> {
9492
{
9593
let mut parameters = HashMap::<&str, String>::new();
9694
parameters.insert("db", database.into());
97-
Client {
95+
Self {
9896
url: Arc::new(url.into()),
9997
parameters: Arc::new(parameters),
10098
client: HttpClient::new(),
10199
token: None,
102-
_version: PhantomData,
100+
version: InfluxDbVersion::V1,
101+
}
102+
}
103+
104+
/// Instantiates a new [`Client`](crate::Client) for InfluxDB v2.
105+
///
106+
/// # Arguments
107+
///
108+
/// * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
109+
/// * `token`: The InfluxDB v2 authentication token.
110+
/// * `bucket`: The InfluxDB v2 bucket.
111+
///
112+
/// # Examples
113+
///
114+
/// ```rust
115+
/// use influxdb::Client;
116+
///
117+
/// let _client = Client::v2("http://localhost:8086", "some-token", "my-bucket");
118+
/// ```
119+
#[must_use = "Creating a client is pointless unless you use it"]
120+
pub fn v2<S1, S2, S3>(url: S1, token: S2, bucket: S3) -> Self
121+
where
122+
S1: Into<String>,
123+
S2: Into<String>,
124+
S3: Into<String>,
125+
{
126+
let mut parameters = HashMap::<&str, String>::new();
127+
parameters.insert("bucket", bucket.into());
128+
Self {
129+
url: Arc::new(url.into()),
130+
parameters: Arc::new(parameters),
131+
client: HttpClient::new(),
132+
token: Some(token.into()),
133+
version: InfluxDbVersion::V2,
134+
}
135+
}
136+
137+
/// Instantiates a new [`Client`](crate::Client) for InfluxDB v3.
138+
///
139+
/// # Arguments
140+
///
141+
/// * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
142+
/// * `token`: The InfluxDB v3 authentication token.
143+
/// * `database`: The InfluxDB v3 database.
144+
///
145+
/// # Examples
146+
///
147+
/// ```rust
148+
/// use influxdb::Client;
149+
///
150+
/// let _client = Client::v3("http://localhost:8086", "some-token", "my-database");
151+
/// ```
152+
#[must_use = "Creating a client is pointless unless you use it"]
153+
pub fn v3<S1, S2, S3>(url: S1, token: S2, database: S3) -> Self
154+
where
155+
S1: Into<String>,
156+
S2: Into<String>,
157+
S3: Into<String>,
158+
{
159+
let mut parameters = HashMap::<&str, String>::new();
160+
parameters.insert("db", database.into());
161+
Self {
162+
url: Arc::new(url.into()),
163+
parameters: Arc::new(parameters),
164+
client: HttpClient::new(),
165+
token: Some(token.into()),
166+
version: InfluxDbVersion::V3,
103167
}
104168
}
105169

@@ -302,16 +366,12 @@ pub(crate) fn check_status(res: &HttpResponse) -> Result<(), Error> {
302366

303367
#[cfg(test)]
304368
mod tests {
305-
306-
use crate::client::InfluxVersion1;
307-
308-
use super::Client;
369+
use super::{Client, InfluxDbVersion};
309370
use indoc::indoc;
310371

311372
#[test]
312373
fn test_client_debug_redacted_password() {
313-
let client: Client<InfluxVersion1> =
314-
Client::new("https://localhost:8086", "db").with_auth("user", "pass");
374+
let client = Client::new("https://localhost:8086", "db").with_auth("user", "pass");
315375
let actual = format!("{client:#?}");
316376
let expected = indoc! { r#"
317377
Client {
@@ -321,6 +381,7 @@ mod tests {
321381
"p": "<redacted>",
322382
"u": "user",
323383
},
384+
version: V1,
324385
..
325386
}
326387
"# };
@@ -329,14 +390,14 @@ mod tests {
329390

330391
#[test]
331392
fn test_fn_database() {
332-
let client: Client<InfluxVersion1> = Client::new("http://localhost:8068", "database");
393+
let client = Client::new("http://localhost:8068", "database");
333394
assert_eq!(client.database_name(), "database");
334395
assert_eq!(client.database_url(), "http://localhost:8068");
335396
}
336397

337398
#[test]
338399
fn test_with_auth() {
339-
let client: Client<InfluxVersion1> = Client::new("http://localhost:8068", "database");
400+
let client = Client::new("http://localhost:8068", "database");
340401
assert_eq!(client.parameters.len(), 1);
341402
assert_eq!(client.parameters.get("db").unwrap(), "database");
342403

@@ -346,10 +407,23 @@ mod tests {
346407
assert_eq!(with_auth.parameters.get("u").unwrap(), "username");
347408
assert_eq!(with_auth.parameters.get("p").unwrap(), "password");
348409

349-
let client: Client<InfluxVersion1> = Client::new("http://localhost:8068", "database");
410+
let client = Client::new("http://localhost:8068", "database");
350411
let with_auth = client.with_token("token");
351412
assert_eq!(with_auth.parameters.len(), 1);
352413
assert_eq!(with_auth.parameters.get("db").unwrap(), "database");
353414
assert_eq!(with_auth.token.unwrap(), "token");
354415
}
416+
417+
#[test]
418+
fn test_v2_and_v3_clients() {
419+
let v2_client = Client::v2("http://localhost:8086", "token", "bucket");
420+
assert_eq!(v2_client.version, InfluxDbVersion::V2);
421+
assert_eq!(v2_client.token.unwrap(), "token");
422+
assert_eq!(v2_client.parameters.get("bucket").unwrap(), "bucket");
423+
424+
let v3_client = Client::v3("http://localhost:8086", "token", "database");
425+
assert_eq!(v3_client.version, InfluxDbVersion::V3);
426+
assert_eq!(v3_client.token.unwrap(), "token");
427+
assert_eq!(v3_client.parameters.get("db").unwrap(), "database");
428+
}
355429
}

influxdb/src/integrations/serde_integration/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub struct TaggedSeries<TAG, T> {
120120
pub values: Vec<T>,
121121
}
122122

123-
impl<V> Client<V, reqwest::Client> {
123+
impl Client<reqwest::Client> {
124124
pub async fn json_query(&self, q: ReadQuery) -> Result<DatabaseQueryResult, Error> {
125125
let query = q.build().map_err(|err| Error::InvalidQueryError {
126126
error: err.to_string(),

0 commit comments

Comments
 (0)