teloxide/src/net/request.rs

135 lines
3.3 KiB
Rust
Raw Normal View History

use std::time::Duration;
2020-08-12 18:39:40 +02:00
use reqwest::{
header::{HeaderValue, CONTENT_TYPE},
Client, Response,
};
use serde::{de::DeserializeOwned, Serialize};
2020-08-12 18:39:40 +02:00
use crate::{
net::{TelegramResponse, TELEGRAM_API_URL},
requests::ResponseResult,
serde_multipart::to_form,
RequestError,
};
2020-08-12 18:39:40 +02:00
const DELAY_ON_SERVER_ERROR: Duration = Duration::from_secs(10);
pub async fn request_multipart<P, R>(
2020-08-12 18:39:40 +02:00
client: &Client,
token: &str,
method_name: &str,
params: &P, // I'll regret this
) -> ResponseResult<R>
2020-08-12 18:39:40 +02:00
where
P: Serialize,
R: DeserializeOwned,
2020-08-12 18:39:40 +02:00
{
use crate::serde_multipart::Error;
let form = match to_form(params).await {
Ok(x) => x,
Err(Error::Io(ioerr)) => return Err(RequestError::Io(ioerr)),
Err(_) => unreachable!(
"we don't create requests those fail to serialize (if you see this, open an issue :|)"
),
};
2020-08-12 18:39:40 +02:00
let response = client
.post(crate::net::method_url(
reqwest::Url::parse(TELEGRAM_API_URL).expect("failed to parse default url"),
token,
method_name,
))
.multipart(form)
2020-08-12 18:39:40 +02:00
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_json<P, R>(
2020-08-12 18:39:40 +02:00
client: &Client,
token: &str,
method_name: &str,
params: &P,
) -> ResponseResult<R>
2020-08-12 18:39:40 +02:00
where
P: Serialize,
R: DeserializeOwned,
2020-08-12 18:39:40 +02:00
{
let response = client
.post(crate::net::method_url(
reqwest::Url::parse(TELEGRAM_API_URL).expect("failed to parse default url"),
token,
method_name,
))
2020-08-12 18:39:40 +02:00
.json(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
// FIXME(waffle):
// request_{json,mutipart} are currently used in old code, so we keep them
// for now when they will not be used anymore, we should remove them
// and rename request_{json,mutipart}2 => request_{json,mutipart}
pub async fn request_multipart2<T>(
client: &Client,
token: &str,
api_url: reqwest::Url,
method_name: &str,
params: reqwest::multipart::Form,
) -> ResponseResult<T>
where
T: DeserializeOwned,
{
let response = client
.post(crate::net::method_url(api_url, token, method_name))
.multipart(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_json2<T>(
client: &Client,
token: &str,
api_url: reqwest::Url,
method_name: &str,
params: Vec<u8>,
) -> ResponseResult<T>
where
T: DeserializeOwned,
{
let response = client
.post(crate::net::method_url(api_url, token, method_name))
.header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
.body(params)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
2020-08-12 18:39:40 +02:00
async fn process_response<T>(response: Response) -> ResponseResult<T>
where
T: DeserializeOwned,
{
if response.status().is_server_error() {
tokio::time::delay_for(DELAY_ON_SERVER_ERROR).await;
}
serde_json::from_str::<TelegramResponse<T>>(
&response.text().await.map_err(RequestError::NetworkError)?,
)
.map_err(RequestError::InvalidJson)?
.into()
}