Skip to content
Snippets Groups Projects
Commit 5dc54938 authored by Maaz Ahmed's avatar Maaz Ahmed
Browse files

refactor: replace external PromqlResult type with internal Data type

This removes the need for the user to import types from the `prometheus-http-query` crate where type annotations are required.
These changes also ensure that the public API of mquery remains more stable, as it is decoupled from the external types.
parent 10b564a4
No related branches found
No related tags found
1 merge request!4Resolve "refactor: Replace QueryResult and Error type with internal types"
......@@ -443,6 +443,7 @@ name = "mquery"
version = "0.2.0"
dependencies = [
"dotenv",
"enum-as-inner",
"prometheus-http-query",
"reqwest",
"tokio",
......
......@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
enum-as-inner = "0.6.0"
prometheus-http-query = "0.8.0"
reqwest = "0.11.22"
url = "2.5.0"
......
......@@ -3,9 +3,10 @@
pub mod query;
pub mod result;
use prometheus_http_query::{response::PromqlResult, Client};
use prometheus_http_query::Client;
use query::IntoQuery;
use reqwest::header::HeaderValue;
use result::{IntoQryResult, QryResult};
use url::Url;
/// The primary way to send queries and get deserialized responses from the metrics server
......@@ -66,7 +67,7 @@ impl QueryManager {
/// The trait is implemented for `&str`, `String`, `&String`, and __mquery's__
/// internal types such as [`query::Metric`], [`query::Scalar`] and others that result
/// from the query builder API.
pub async fn query<Q: IntoQuery>(&self, query: Q) -> Result<PromqlResult, result::Error> {
pub async fn query<Q: IntoQuery>(&self, query: Q) -> QryResult {
let mut builder = self.client.query(query.into_query().as_ref());
if let Some((name, val)) = self.auth.get_header() {
builder = builder.header(name, val);
......@@ -75,8 +76,8 @@ impl QueryManager {
builder = builder.timeout(*timeout);
}
match self.method {
Method::Get => builder.get().await.map_err(|e| e.into()),
Method::Post => builder.post().await.map_err(|e| e.into()),
Method::Get => builder.get().await.into_qry_result(),
Method::Post => builder.post().await.into_qry_result(),
}
}
......@@ -92,7 +93,7 @@ impl QueryManager {
start: i64,
end: i64,
step: f64,
) -> Result<PromqlResult, result::Error> {
) -> QryResult {
let mut builder = self
.client
.query_range(query.into_query().as_ref(), start, end, step);
......@@ -103,8 +104,8 @@ impl QueryManager {
builder = builder.timeout(*timeout);
}
match self.method {
Method::Get => builder.get().await.map_err(|e| e.into()),
Method::Post => builder.post().await.map_err(|e| e.into()),
Method::Get => builder.get().await.into_qry_result(),
Method::Post => builder.post().await.into_qry_result(),
}
}
}
......
//! `PromqlResult` and the `Error` types which are essentially clones of the types
//! `Data` and the `Error` types which are essentially clones of the types
//! with the same name from the `prometheus-http-query` crate with slight modifications
//! to suit the needs of `mqeury`.
//!
//! The reason why this crate maintains its own types which are the same (almost) as the ones
//! Another reason why this crate maintains its own types which are the same (almost) as the ones
//! provided by the other crate that is used internally, is to ensure that the public
//! API remains stable even if the internal crate API changes.
use prometheus_http_query::error;
use enum_as_inner::EnumAsInner;
use prometheus_http_query::{error, response};
use std::fmt::{self, Display};
pub type QryResult = std::result::Result<Data, Error>;
/// Internal trait used for converting the `prometheus-http-query` crate's query result into the internal result type
pub(crate) trait IntoQryResult {
fn into_qry_result(self) -> QryResult;
}
impl IntoQryResult for Result<response::PromqlResult, error::Error> {
fn into_qry_result(self) -> QryResult {
self.map(|r| r.into()).map_err(|e| e.into())
}
}
/// A wrapper for possible result types of expression queries ([`Client::query`](crate::Client::query) and [`Client::query_range`](crate::Client::query_range)).
#[derive(Clone, Debug, EnumAsInner)]
pub enum Data {
Vector(Vec<response::InstantVector>),
Matrix(Vec<response::RangeVector>),
Scalar(response::Sample),
}
impl From<response::PromqlResult> for Data {
fn from(value: response::PromqlResult) -> Self {
let (data, _) = value.into_inner();
match data {
response::Data::Vector(v) => Data::Vector(v),
response::Data::Matrix(m) => Data::Matrix(m),
response::Data::Scalar(s) => Data::Scalar(s),
}
}
}
impl Data {
/// This is a shortcut to check if the query returned any data at all regardless of the exact type.
pub fn is_empty(&self) -> bool {
match self {
Data::Vector(v) => v.is_empty(),
Data::Matrix(v) => v.is_empty(),
Data::Scalar(_) => false,
}
}
}
/// A global error enum that contains all errors that are returned by this
/// library. Some errors are wrappers for errors from underlying libraries.
/// All errors (this enum as well as all contained structs) implement [`std::error::Error`].
......
use mquery::{query::IntoQuery, QueryManager};
use prometheus_http_query::response::PromqlResult;
use mquery::{query::IntoQuery, result::QryResult, QueryManager};
// local victoria metrics server
pub static URL: &str = "http://localhost:8428";
pub async fn send_query(query: impl IntoQuery) -> Result<PromqlResult, mquery::result::Error> {
pub async fn send_query(query: impl IntoQuery) -> QryResult {
QueryManager::new(URL.parse().unwrap()).query(query).await
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment