use std::time::Duration;
use reqwest::{
header::{HeaderValue, CONTENT_TYPE},
Client, Response,
};
use serde::{de::DeserializeOwned, Serialize};
use crate::{
net::{TelegramResponse, TELEGRAM_API_URL},
requests::ResponseResult,
serde_multipart::to_form,
RequestError,
};
const DELAY_ON_SERVER_ERROR: Duration = Duration::from_secs(10);
pub async fn request_multipart
(
client: &Client,
token: &str,
method_name: &str,
params: &P, // I'll regret this
) -> ResponseResult
where
P: Serialize,
R: DeserializeOwned,
{
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 :|)"
),
};
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)
.send()
.await
.map_err(RequestError::NetworkError)?;
process_response(response).await
}
pub async fn request_json(
client: &Client,
token: &str,
method_name: &str,
params: &P,
) -> ResponseResult
where
P: Serialize,
R: DeserializeOwned,
{
let response = client
.post(crate::net::method_url(
reqwest::Url::parse(TELEGRAM_API_URL).expect("failed to parse default url"),
token,
method_name,
))
.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(
client: &Client,
token: &str,
api_url: reqwest::Url,
method_name: &str,
params: reqwest::multipart::Form,
) -> ResponseResult
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(
client: &Client,
token: &str,
api_url: reqwest::Url,
method_name: &str,
params: Vec,
) -> ResponseResult
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
}
async fn process_response(response: Response) -> ResponseResult
where
T: DeserializeOwned,
{
if response.status().is_server_error() {
tokio::time::delay_for(DELAY_ON_SERVER_ERROR).await;
}
serde_json::from_str::>(
&response.text().await.map_err(RequestError::NetworkError)?,
)
.map_err(RequestError::InvalidJson)?
.into()
}