Split client into two modules
Signed-off-by: trivernis <trivernis@protonmail.com>main
parent
f0b669991d
commit
642a6c3b55
@ -1,108 +0,0 @@
|
|||||||
pub use crate::endpoints::*;
|
|
||||||
use crate::{ClientBuilder, Error, Result};
|
|
||||||
use flate2::write::ZlibDecoder;
|
|
||||||
use reqwest::Response;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
pub struct Client {
|
|
||||||
pub(crate) client: reqwest::Client,
|
|
||||||
pub(crate) base_url: String,
|
|
||||||
pub(crate) access_key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
/// Creates a new client builder
|
|
||||||
pub fn builder() -> ClientBuilder {
|
|
||||||
ClientBuilder::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new PTR Client
|
|
||||||
pub fn new<S1: ToString, S2: ToString>(endpoint: S1, access_key: S2) -> Self {
|
|
||||||
Self {
|
|
||||||
base_url: endpoint.to_string(),
|
|
||||||
client: reqwest::Client::new(),
|
|
||||||
access_key: access_key.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the options of the PTR
|
|
||||||
#[tracing::instrument(skip(self), level = "debug")]
|
|
||||||
pub async fn get_options(&self) -> Result<OptionsResponse> {
|
|
||||||
self.get::<OptionsEndpoint, ()>(&()).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns information about all available updates since the given ID
|
|
||||||
/// and when the next check for updates should be made
|
|
||||||
#[tracing::instrument(skip(self), level = "debug")]
|
|
||||||
pub async fn get_metadata(&self, since: u64) -> Result<MetadataResponse> {
|
|
||||||
self.get::<MetadataEndpoint, _>(&[("since", since)]).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the parsed update file identified by the given hash.
|
|
||||||
/// The hash can be retrieved by fetching the metadata with [Client::metadata]
|
|
||||||
#[tracing::instrument(skip(self), level = "debug")]
|
|
||||||
pub async fn get_update<S: AsRef<str> + Debug>(
|
|
||||||
&self,
|
|
||||||
update_hash: S,
|
|
||||||
) -> Result<UpdateResponse> {
|
|
||||||
self.get::<UpdateEndpoint, _>(&[("update_hash", update_hash.as_ref())])
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs a get request to the given Get Endpoint
|
|
||||||
#[tracing::instrument(skip(self), level = "trace")]
|
|
||||||
async fn get<E: GetEndpoint, Q: Serialize + Debug>(&self, query: &Q) -> Result<E::Response> {
|
|
||||||
tracing::trace!("GET request to {}", E::path());
|
|
||||||
let response = self
|
|
||||||
.client
|
|
||||||
.get(format!("{}/{}", self.base_url, E::path()))
|
|
||||||
.query(query)
|
|
||||||
.header("Hydrus-Key", self.access_key.to_string())
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
let body = Self::get_body(response).await?;
|
|
||||||
let bytes = Self::decompress_body(body)?;
|
|
||||||
let response_type = Self::deserialize_body(bytes)?;
|
|
||||||
tracing::trace!("response is: {:?}", response_type);
|
|
||||||
|
|
||||||
Ok(response_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the body from the response
|
|
||||||
#[tracing::instrument(level = "trace")]
|
|
||||||
async fn get_body(response: Response) -> Result<Vec<u8>> {
|
|
||||||
if response.status().is_success() {
|
|
||||||
Ok(response.bytes().await?.to_vec())
|
|
||||||
} else {
|
|
||||||
let message = response.text().await?;
|
|
||||||
Err(Error::Response(message))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Uses zlib to decompress the body
|
|
||||||
#[tracing::instrument(skip(bytes), level = "trace")]
|
|
||||||
fn decompress_body(mut bytes: Vec<u8>) -> Result<Vec<u8>> {
|
|
||||||
tracing::trace!("body length {}", bytes.len());
|
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
|
||||||
let mut decoder = ZlibDecoder::new(buf);
|
|
||||||
|
|
||||||
decoder.write_all(&mut bytes)?;
|
|
||||||
buf = decoder.finish()?;
|
|
||||||
|
|
||||||
tracing::trace!("result length {}", buf.len());
|
|
||||||
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deserializes the body to the given type
|
|
||||||
#[tracing::instrument(skip(bytes), level = "trace")]
|
|
||||||
fn deserialize_body<T: FromJson>(bytes: Vec<u8>) -> Result<T> {
|
|
||||||
let json_value: serde_json::Value = serde_json::from_reader(&bytes[..])?;
|
|
||||||
tracing::trace!("json value = {}", json_value.to_string());
|
|
||||||
|
|
||||||
T::from_json(json_value)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,66 @@
|
|||||||
|
use crate::{Client, Error, FromJson, GetEndpoint};
|
||||||
|
use flate2::write::ZlibDecoder;
|
||||||
|
use reqwest::Response;
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Performs a get request to the given Get Endpoint
|
||||||
|
#[tracing::instrument(skip(self), level = "trace")]
|
||||||
|
pub(crate) async fn get<E: GetEndpoint, Q: Serialize + Debug>(
|
||||||
|
&self,
|
||||||
|
query: &Q,
|
||||||
|
) -> crate::Result<E::Response> {
|
||||||
|
tracing::trace!("GET request to {}", E::path());
|
||||||
|
let response = self
|
||||||
|
.client
|
||||||
|
.get(format!("{}/{}", self.base_url, E::path()))
|
||||||
|
.query(query)
|
||||||
|
.header("Hydrus-Key", self.access_key.to_string())
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
let body = Self::get_body(response).await?;
|
||||||
|
let bytes = Self::decompress_body(body)?;
|
||||||
|
let response_type = Self::deserialize_body(bytes)?;
|
||||||
|
tracing::trace!("response is: {:?}", response_type);
|
||||||
|
|
||||||
|
Ok(response_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the body from the response
|
||||||
|
#[tracing::instrument(level = "trace")]
|
||||||
|
async fn get_body(response: Response) -> crate::Result<Vec<u8>> {
|
||||||
|
if response.status().is_success() {
|
||||||
|
Ok(response.bytes().await?.to_vec())
|
||||||
|
} else {
|
||||||
|
let message = response.text().await?;
|
||||||
|
Err(Error::Response(message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Uses zlib to decompress the body
|
||||||
|
#[tracing::instrument(skip(bytes), level = "trace")]
|
||||||
|
fn decompress_body(mut bytes: Vec<u8>) -> crate::Result<Vec<u8>> {
|
||||||
|
tracing::trace!("body length {}", bytes.len());
|
||||||
|
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let mut decoder = ZlibDecoder::new(buf);
|
||||||
|
|
||||||
|
decoder.write_all(&mut bytes)?;
|
||||||
|
buf = decoder.finish()?;
|
||||||
|
|
||||||
|
tracing::trace!("result length {}", buf.len());
|
||||||
|
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserializes the body to the given type
|
||||||
|
#[tracing::instrument(skip(bytes), level = "trace")]
|
||||||
|
fn deserialize_body<T: FromJson>(bytes: Vec<u8>) -> crate::Result<T> {
|
||||||
|
let json_value: serde_json::Value = serde_json::from_reader(&bytes[..])?;
|
||||||
|
tracing::trace!("json value = {}", json_value.to_string());
|
||||||
|
|
||||||
|
T::from_json(json_value)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
mod client_core;
|
||||||
|
|
||||||
|
pub use crate::endpoints::*;
|
||||||
|
use crate::{ClientBuilder, Result};
|
||||||
|
pub use client_core::*;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
pub(crate) client: reqwest::Client,
|
||||||
|
pub(crate) base_url: String,
|
||||||
|
pub(crate) access_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Creates a new client builder
|
||||||
|
pub fn builder() -> ClientBuilder {
|
||||||
|
ClientBuilder::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new PTR Client
|
||||||
|
pub fn new<S1: ToString, S2: ToString>(endpoint: S1, access_key: S2) -> Self {
|
||||||
|
Self {
|
||||||
|
base_url: endpoint.to_string(),
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
access_key: access_key.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the options of the PTR
|
||||||
|
#[tracing::instrument(skip(self), level = "debug")]
|
||||||
|
pub async fn get_options(&self) -> Result<OptionsResponse> {
|
||||||
|
self.get::<OptionsEndpoint, ()>(&()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns information about all available updates since the given ID
|
||||||
|
/// and when the next check for updates should be made
|
||||||
|
#[tracing::instrument(skip(self), level = "debug")]
|
||||||
|
pub async fn get_metadata(&self, since: u64) -> Result<MetadataResponse> {
|
||||||
|
self.get::<MetadataEndpoint, _>(&[("since", since)]).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the parsed update file identified by the given hash.
|
||||||
|
/// The hash can be retrieved by fetching the metadata with [Client::metadata]
|
||||||
|
#[tracing::instrument(skip(self), level = "debug")]
|
||||||
|
pub async fn get_update<S: AsRef<str> + Debug>(
|
||||||
|
&self,
|
||||||
|
update_hash: S,
|
||||||
|
) -> Result<UpdateResponse> {
|
||||||
|
self.get::<UpdateEndpoint, _>(&[("update_hash", update_hash.as_ref())])
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue