Add dynamic::{Kind, Payload, Request} (they are needed for storing _some_ request with concrete output)

This commit is contained in:
Waffle 2019-11-05 00:28:36 +03:00
parent b788da0608
commit 0b750f2ac1
4 changed files with 112 additions and 27 deletions

View file

@ -3,7 +3,7 @@ pub use download::download_file_stream;
pub use self::{
download::download_file,
request::{request_json, request_multipart, request_simple},
request::{request_json, request_multipart, request_simple, request_dynamic},
telegram_response::TelegramResponse,
};

View file

@ -14,15 +14,14 @@ pub async fn request_multipart<T>(
where
T: DeserializeOwned,
{
process_response(
client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.multipart(params)
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
let response = client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.multipart(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_simple<T>(
@ -33,14 +32,13 @@ pub async fn request_simple<T>(
where
T: DeserializeOwned,
{
process_response(
client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
let response = client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_json<T, P>(
@ -53,15 +51,56 @@ where
T: DeserializeOwned,
P: Serialize,
{
process_response(
client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.json(params)
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
let response = client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.json(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_body<T>(
client: &Client,
token: &str,
method_name: &str,
params: String,
) -> ResponseResult<T>
where
T: DeserializeOwned,
{
let response = client
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
.body(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_dynamic<T>(
client: &Client,
token: &str,
method_name: &str,
params: crate::requests::dynamic::Kind,
) -> ResponseResult<T>
where
T: DeserializeOwned,
{
use crate::requests::dynamic::Kind;
match params {
Kind::Simple => request_simple(client, token, method_name).await,
Kind::Json(str) => request_body(client, token, method_name, str).await,
Kind::Multipart(form) => request_multipart(
client,
token,
method_name,
form
).await
}
}
async fn process_response<T>(response: Response) -> ResponseResult<T>

45
src/requests/dynamic.rs Normal file
View file

@ -0,0 +1,45 @@
use serde::de::DeserializeOwned;
use reqwest::multipart;
use crate::{Bot, network};
use super::{ResponseResult, Method};
pub enum Kind {
Simple,
Json(String),
Multipart(multipart::Form),
}
pub trait Payload {
// NOTE: This payload doesn't use `Method` and reinvent `type Output`
// because the trait `Method` cannot be made into an object.
type Output;
fn method(&self) -> &str;
fn kind(&self) -> Kind;
}
pub struct Request<'b, P> {
bot: &'b Bot,
pub(crate) payload: P,
}
impl<'b, P> Request<'b, P>
where
P: Payload,
P::Output: DeserializeOwned,
{
pub fn new(bot: &'b Bot, payload: P) -> Self {
Self { bot, payload }
}
pub async fn send(&self) -> ResponseResult<P::Output> {
network::request_dynamic(
self.bot.client(),
self.bot.token(),
self.payload.method(),
self.payload.kind(),
).await
}
}

View file

@ -118,3 +118,4 @@ pub trait Method {
pub mod json;
pub mod multipart;
pub mod simple;
pub mod dynamic;