diff --git a/src/client/mod.rs b/src/client/mod.rs index 869afac..c25f8e2 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -22,11 +22,7 @@ use reqwest::{StatusCode, Url}; use std::mem; use crate::error::InfluxDbError; -use crate::query::read_query::InfluxDbReadQuery; -use crate::query::write_query::InfluxDbWriteQuery; -use crate::query::InfluxDbQuery; - -use std::any::Any; +use crate::query::{InfluxDbQuery, InfluxDbQueryTypes}; #[derive(Clone, Debug)] /// Internal Authentication representation @@ -184,9 +180,10 @@ impl InfluxDbClient { /// a [`InfluxDbError`] variant will be returned. /// /// [`InfluxDbError`]: enum.InfluxDbError.html - pub fn query(&self, q: &Q) -> Box> + pub fn query<'q, Q>(&self, q: &'q Q) -> Box> where - Q: Any + InfluxDbQuery, + Q: InfluxDbQuery, + &'q Q: Into>, { use futures::future; @@ -200,49 +197,48 @@ impl InfluxDbClient { Ok(query) => query, }; - let any_value = q as &dyn Any; let basic_parameters: Vec<(String, String)> = self.into(); - let client = if let Some(_) = any_value.downcast_ref::() { - let read_query = query.get(); + let client = match q.into() { + InfluxDbQueryTypes::Read(_) => { + let read_query = query.get(); + let mut url = match Url::parse_with_params( + format!("{url}/query", url = self.database_url()).as_str(), + basic_parameters, + ) { + Ok(url) => url, + Err(err) => { + let error = InfluxDbError::UrlConstructionError { + error: format!("{}", err), + }; + return Box::new(future::err::(error)); + } + }; + url.query_pairs_mut().append_pair("q", &read_query.clone()); - let mut url = match Url::parse_with_params( - format!("{url}/query", url = self.database_url()).as_str(), - basic_parameters, - ) { - Ok(url) => url, - Err(err) => { - let error = InfluxDbError::UrlConstructionError { - error: format!("{}", err), - }; - return Box::new(future::err::(error)); + if read_query.contains("SELECT") || read_query.contains("SHOW") { + Client::new().get(url) + } else { + Client::new().post(url) } - }; - url.query_pairs_mut().append_pair("q", &read_query.clone()); - - if read_query.contains("SELECT") || read_query.contains("SHOW") { - Client::new().get(url) - } else { - Client::new().post(url) } - } else if let Some(write_query) = any_value.downcast_ref::() { - let mut url = match Url::parse_with_params( - format!("{url}/write", url = self.database_url()).as_str(), - basic_parameters, - ) { - Ok(url) => url, - Err(err) => { - let error = InfluxDbError::InvalidQueryError { - error: format!("{}", err), - }; - return Box::new(future::err::(error)); - } - }; - url.query_pairs_mut() - .append_pair("precision", &write_query.get_precision()); - Client::new().post(url).body(query.get()) - } else { - unreachable!() + InfluxDbQueryTypes::Write(write_query) => { + let mut url = match Url::parse_with_params( + format!("{url}/write", url = self.database_url()).as_str(), + basic_parameters, + ) { + Ok(url) => url, + Err(err) => { + let error = InfluxDbError::InvalidQueryError { + error: format!("{}", err), + }; + return Box::new(future::err::(error)); + } + }; + url.query_pairs_mut() + .append_pair("precision", &write_query.get_precision()); + Client::new().post(url).body(query.get()) + } }; Box::new( client diff --git a/src/query/mod.rs b/src/query/mod.rs index f462a4f..353daca 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -50,6 +50,24 @@ impl fmt::Display for Timestamp { } } +/// Internal enum used to represent either type of query. +pub enum InfluxDbQueryTypes<'a> { + Read(&'a InfluxDbReadQuery), + Write(&'a InfluxDbWriteQuery), +} + +impl<'a> From<&'a InfluxDbReadQuery> for InfluxDbQueryTypes<'a> { + fn from(query: &'a InfluxDbReadQuery) -> Self { + Self::Read(query) + } +} + +impl<'a> From<&'a InfluxDbWriteQuery> for InfluxDbQueryTypes<'a> { + fn from(query: &'a InfluxDbWriteQuery) -> Self { + Self::Write(query) + } +} + pub trait InfluxDbQuery { /// Builds valid InfluxSQL which can be run against the Database. /// In case no fields have been specified, it will return an error, @@ -71,7 +89,7 @@ pub trait InfluxDbQuery { fn get_type(&self) -> QueryType; } -impl InfluxDbQuery { +impl dyn InfluxDbQuery { /// Returns a [`InfluxDbWriteQuery`](crate::query::write_query::InfluxDbWriteQuery) builder. /// /// # Examples