mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-03 09:49:07 +01:00
Rework Request
trait
This commit is contained in:
parent
6de592fa6b
commit
3f88c45d6b
4 changed files with 68 additions and 83 deletions
|
@ -1,14 +1,16 @@
|
||||||
use apply::Apply;
|
|
||||||
use futures::compat::Future01CompatExt;
|
use futures::compat::Future01CompatExt;
|
||||||
use reqwest::r#async::Client;
|
|
||||||
use reqwest::StatusCode;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use reqwest::{
|
||||||
|
r#async::{Client, multipart::Form},
|
||||||
|
StatusCode,
|
||||||
|
};
|
||||||
|
use apply::Apply;
|
||||||
|
|
||||||
use super::requests::Request;
|
|
||||||
|
|
||||||
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
||||||
|
|
||||||
|
|
||||||
/// Create url for macking requests, see [telegram docs](https://core.telegram.org/bots/api#making-requests)
|
/// Create url for macking requests, see [telegram docs](https://core.telegram.org/bots/api#making-requests)
|
||||||
fn method_url(base: &str, token: &str, method_name: &str) -> String {
|
fn method_url(base: &str, token: &str, method_name: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
|
@ -56,18 +58,16 @@ impl std::error::Error for RequestError {
|
||||||
|
|
||||||
pub type ResponseResult<T> = Result<T, RequestError>;
|
pub type ResponseResult<T> = Result<T, RequestError>;
|
||||||
|
|
||||||
pub async fn request<T: DeserializeOwned, R: Request<ReturnValue = T>>(
|
pub async fn request<T: DeserializeOwned>(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
request: R,
|
token: &str,
|
||||||
|
method_name: &str,
|
||||||
|
params: Option<Form>,
|
||||||
) -> ResponseResult<T> {
|
) -> ResponseResult<T> {
|
||||||
let mut response = client
|
let mut response = client
|
||||||
.post(&method_url(
|
.post(&method_url(TELEGRAM_API_URL, token, method_name))
|
||||||
TELEGRAM_API_URL,
|
|
||||||
request.token(),
|
|
||||||
request.name(),
|
|
||||||
))
|
|
||||||
.apply(|request_builder| {
|
.apply(|request_builder| {
|
||||||
if let Some(params) = request.params() {
|
if let Some(params) = params {
|
||||||
request_builder.multipart(params)
|
request_builder.multipart(params)
|
||||||
} else {
|
} else {
|
||||||
request_builder
|
request_builder
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
use reqwest::r#async::multipart::Form;
|
use crate::core::{
|
||||||
|
types::User,
|
||||||
|
network::{
|
||||||
|
request, ResponseResult,
|
||||||
|
},
|
||||||
|
requests::{
|
||||||
|
Request, RequestInfo, RequestFuture,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
use crate::core::types::User;
|
|
||||||
|
|
||||||
use super::Request;
|
#[derive(Debug, Constructor)]
|
||||||
|
|
||||||
#[derive(Debug, Constructor, PartialEq, Eq)]
|
|
||||||
pub struct GetMe {
|
pub struct GetMe {
|
||||||
token: String,
|
info: RequestInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Request for GetMe {
|
impl Request for GetMe {
|
||||||
type ReturnValue = User;
|
type ReturnValue = User;
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>> {
|
||||||
"getMe"
|
Box::new(async {
|
||||||
}
|
request(&self.info.client, &self.info.token, "getMe", None).await
|
||||||
fn params(self) -> Option<Form> {
|
})
|
||||||
None
|
|
||||||
}
|
|
||||||
fn token(&self) -> &str {
|
|
||||||
&self.token
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,30 @@
|
||||||
use reqwest::r#async::multipart::Form;
|
use std::future::Future;
|
||||||
|
|
||||||
|
use crate::core::network::ResponseResult;
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
use reqwest::r#async::Client;
|
||||||
|
|
||||||
|
|
||||||
mod form_builder;
|
mod form_builder;
|
||||||
|
|
||||||
/// Request that can be sended to telegram.
|
|
||||||
|
/// Request that can be sent to telegram.
|
||||||
/// `ReturnValue` - a type that will be returned from Telegram.
|
/// `ReturnValue` - a type that will be returned from Telegram.
|
||||||
pub trait Request {
|
pub trait Request {
|
||||||
type ReturnValue: DeserializeOwned;
|
type ReturnValue: DeserializeOwned;
|
||||||
|
|
||||||
/// Get name of the request (e.g. "getMe" or "sendMessage")
|
/// Send request to telegram
|
||||||
fn name(&self) -> &str;
|
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Form with params
|
pub type RequestFuture<T> = Box<dyn Future<Output = T>>;
|
||||||
fn params(self) -> Option<Form>;
|
|
||||||
|
|
||||||
/// Bot token
|
// todo: better name?
|
||||||
fn token(&self) -> &str;
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RequestInfo {
|
||||||
|
pub(crate) client: Client,
|
||||||
|
pub(crate) token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unique identifier for the target chat or username of the target channel (in
|
/// Unique identifier for the target chat or username of the target channel (in
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
use reqwest::r#async::multipart::Form;
|
use crate::core::{
|
||||||
|
types::Message,
|
||||||
|
network::{
|
||||||
|
request, ResponseResult,
|
||||||
|
},
|
||||||
|
requests::{
|
||||||
|
form_builder::FormBuilder,
|
||||||
|
ChatId,
|
||||||
|
Request,
|
||||||
|
RequestInfo,
|
||||||
|
RequestFuture,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
use crate::core::types::Message;
|
|
||||||
|
|
||||||
use super::form_builder::FormBuilder;
|
#[derive(Debug, TypedBuilder)]
|
||||||
use super::{ChatId, Request};
|
|
||||||
|
|
||||||
#[derive(Debug, TypedBuilder, PartialEq, Eq)]
|
|
||||||
pub struct SendMessage {
|
pub struct SendMessage {
|
||||||
token: String,
|
info: RequestInfo,
|
||||||
|
|
||||||
chat_id: ChatId,
|
chat_id: ChatId,
|
||||||
text: String,
|
text: String,
|
||||||
|
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
parse_mode: Option<String>,
|
parse_mode: Option<String>, // TODO: ParseMode enum
|
||||||
// TODO: enum
|
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
disable_web_page_preview: Option<bool>,
|
disable_web_page_preview: Option<bool>,
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
|
@ -27,12 +35,10 @@ pub struct SendMessage {
|
||||||
impl Request for SendMessage {
|
impl Request for SendMessage {
|
||||||
type ReturnValue = Message;
|
type ReturnValue = Message;
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
|
||||||
"getMe"
|
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>> {
|
||||||
}
|
Box::new(async {
|
||||||
fn params(self) -> Option<Form> {
|
let params = FormBuilder::new()
|
||||||
Some(
|
|
||||||
FormBuilder::new()
|
|
||||||
.add("chat_id", &self.chat_id)
|
.add("chat_id", &self.chat_id)
|
||||||
.add("text", &self.text)
|
.add("text", &self.text)
|
||||||
.add_if_some("parse_mode", self.parse_mode.as_ref())
|
.add_if_some("parse_mode", self.parse_mode.as_ref())
|
||||||
|
@ -42,40 +48,9 @@ impl Request for SendMessage {
|
||||||
)
|
)
|
||||||
.add_if_some("disable_notification", self.disable_notification.as_ref())
|
.add_if_some("disable_notification", self.disable_notification.as_ref())
|
||||||
.add_if_some("reply_to_message_id", self.reply_to_message_id.as_ref())
|
.add_if_some("reply_to_message_id", self.reply_to_message_id.as_ref())
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// .add_if_some("reply_markup",
|
|
||||||
// self.reply_markup.as_ref()))
|
|
||||||
}
|
|
||||||
fn token(&self) -> &str {
|
|
||||||
&self.token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn default() {
|
|
||||||
let sm = SendMessage::builder()
|
|
||||||
.token("TOKEN")
|
|
||||||
.chat_id(123456.into())
|
|
||||||
.text("text")
|
|
||||||
.build();
|
.build();
|
||||||
let r = SendMessage {
|
|
||||||
token: String::from("TOKEN"),
|
|
||||||
chat_id: ChatId::Id(123456),
|
|
||||||
text: String::from("text"),
|
|
||||||
parse_mode: None,
|
|
||||||
disable_web_page_preview: None,
|
|
||||||
disable_notification: None,
|
|
||||||
reply_to_message_id: None,
|
|
||||||
reply_markup: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(sm, r);
|
request(&self.info.client, &self.info.token, "sendMessage", Some(params)).await
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue