mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Merge branch 'dev' of github.com:async-telegram-bot/async-telegram-bot into dev
This commit is contained in:
commit
9f8396f752
12 changed files with 88 additions and 111 deletions
|
@ -1,3 +1,3 @@
|
|||
pub mod network;
|
||||
mod network;
|
||||
pub mod requests;
|
||||
pub mod types;
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
use apply::Apply;
|
||||
use futures::compat::Future01CompatExt;
|
||||
use reqwest::r#async::{multipart::Form, Client};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::Value;
|
||||
use reqwest::{
|
||||
r#async::{Client, multipart::Form},
|
||||
StatusCode,
|
||||
};
|
||||
use apply::Apply;
|
||||
|
||||
use crate::core::requests::{RequestError, ResponseResult};
|
||||
|
||||
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)
|
||||
/// Creates URL for making HTTPS requests. See the [Telegram documentation].
|
||||
///
|
||||
/// [Telegram documentation]: https://core.telegram.org/bots/api#making-requests
|
||||
fn method_url(base: &str, token: &str, method_name: &str) -> String {
|
||||
format!(
|
||||
"{url}/bot{token}/{method}",
|
||||
|
@ -21,7 +20,9 @@ fn method_url(base: &str, token: &str, method_name: &str) -> String {
|
|||
)
|
||||
}
|
||||
|
||||
/// Create url for downloading file, see [telegram docs](https://core.telegram.org/bots/api#file)
|
||||
/// Creates URL for downloading a file. See the [Telegram documentation].
|
||||
///
|
||||
/// [Telegram documentation] (https://core.telegram.org/bots/api#file)
|
||||
fn file_url(base: &str, token: &str, file_path: &str) -> String {
|
||||
format!(
|
||||
"{url}/file/bot{token}/{file}",
|
||||
|
@ -31,33 +32,6 @@ fn file_url(base: &str, token: &str, file_path: &str) -> String {
|
|||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
pub enum RequestError {
|
||||
#[display(fmt = "Telegram error #{}: {}", status_code, description)]
|
||||
ApiError {
|
||||
status_code: StatusCode,
|
||||
description: String,
|
||||
},
|
||||
|
||||
#[display(fmt = "Network error: {err}", err = _0)]
|
||||
NetworkError(reqwest::Error),
|
||||
|
||||
#[display(fmt = "InvalidJson error caused by: {err}", err = _0)]
|
||||
InvalidJson(serde_json::Error),
|
||||
}
|
||||
|
||||
impl std::error::Error for RequestError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
RequestError::ApiError { .. } => None,
|
||||
RequestError::NetworkError(err) => Some(err),
|
||||
RequestError::InvalidJson(err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type ResponseResult<T> = Result<T, RequestError>;
|
||||
|
||||
pub async fn request<T: DeserializeOwned>(
|
||||
client: &Client,
|
||||
token: &str,
|
||||
|
@ -66,12 +40,9 @@ pub async fn request<T: DeserializeOwned>(
|
|||
) -> ResponseResult<T> {
|
||||
let mut response = client
|
||||
.post(&method_url(TELEGRAM_API_URL, token, method_name))
|
||||
.apply(|request_builder| {
|
||||
if let Some(params) = params {
|
||||
request_builder.multipart(params)
|
||||
} else {
|
||||
request_builder
|
||||
}
|
||||
.apply(|request_builder| match params {
|
||||
Some(params) => request_builder.multipart(params),
|
||||
None => request_builder,
|
||||
})
|
||||
.send()
|
||||
.compat()
|
||||
|
|
|
@ -38,8 +38,8 @@ impl FormBuilder {
|
|||
form: self.form.text(
|
||||
name.to_owned(),
|
||||
serde_json::to_string(value).expect("serde_json::to_string failed"),
|
||||
)
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
use crate::core::{
|
||||
types::User,
|
||||
network::{
|
||||
request, ResponseResult,
|
||||
},
|
||||
requests::{
|
||||
Request, RequestInfo, RequestFuture,
|
||||
}
|
||||
};
|
||||
|
||||
use crate::core::network;
|
||||
use crate::core::requests::{Request, RequestFuture, RequestInfo, ResponseResult};
|
||||
use crate::core::types::User;
|
||||
|
||||
#[derive(Debug, Constructor)]
|
||||
pub struct GetMe {
|
||||
info: RequestInfo
|
||||
info: RequestInfo,
|
||||
}
|
||||
|
||||
impl Request for GetMe {
|
||||
|
@ -19,7 +12,7 @@ impl Request for GetMe {
|
|||
|
||||
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>> {
|
||||
Box::new(async move {
|
||||
request(&self.info.client, &self.info.token, "getMe", None).await
|
||||
network::request(&self.info.client, &self.info.token, "getMe", None).await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,37 @@
|
|||
use std::future::Future;
|
||||
|
||||
use crate::core::network::ResponseResult;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use reqwest::r#async::Client;
|
||||
|
||||
use reqwest::StatusCode;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
mod form_builder;
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
pub enum RequestError {
|
||||
#[display(fmt = "Telegram error #{}: {}", status_code, description)]
|
||||
ApiError {
|
||||
status_code: StatusCode,
|
||||
description: String,
|
||||
},
|
||||
|
||||
#[display(fmt = "Network error: {err}", err = _0)]
|
||||
NetworkError(reqwest::Error),
|
||||
|
||||
#[display(fmt = "InvalidJson error caused by: {err}", err = _0)]
|
||||
InvalidJson(serde_json::Error),
|
||||
}
|
||||
|
||||
impl std::error::Error for RequestError {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
match self {
|
||||
RequestError::ApiError { .. } => None,
|
||||
RequestError::NetworkError(err) => Some(err),
|
||||
RequestError::InvalidJson(err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type ResponseResult<T> = Result<T, RequestError>;
|
||||
|
||||
/// Request that can be sent to telegram.
|
||||
/// `ReturnValue` - a type that will be returned from Telegram.
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
use crate::core::{
|
||||
types::Message,
|
||||
network::{
|
||||
request, ResponseResult,
|
||||
},
|
||||
requests::{
|
||||
form_builder::FormBuilder,
|
||||
ChatId,
|
||||
Request,
|
||||
RequestInfo,
|
||||
RequestFuture,
|
||||
}
|
||||
};
|
||||
|
||||
use crate::core::requests::form_builder::FormBuilder;
|
||||
use crate::core::requests::{ChatId, Request, RequestFuture, RequestInfo, ResponseResult};
|
||||
use crate::core::{network, types::Message};
|
||||
|
||||
#[derive(Debug, TypedBuilder)]
|
||||
pub struct SendMessage {
|
||||
|
@ -35,7 +24,6 @@ pub struct SendMessage {
|
|||
impl Request for SendMessage {
|
||||
type ReturnValue = Message;
|
||||
|
||||
|
||||
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>> {
|
||||
Box::new(async move {
|
||||
let params = FormBuilder::new()
|
||||
|
@ -50,7 +38,13 @@ impl Request for SendMessage {
|
|||
.add_if_some("reply_to_message_id", self.reply_to_message_id.as_ref())
|
||||
.build();
|
||||
|
||||
request(&self.info.client, &self.info.token, "sendMessage", Some(params)).await
|
||||
network::request(
|
||||
&self.info.client,
|
||||
&self.info.token,
|
||||
"sendMessage",
|
||||
Some(params),
|
||||
)
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::core::types::user::User;
|
||||
|
||||
#[derive(Debug, Deserealize)]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::core::parse_mode::ParseMode;
|
||||
|
||||
pub enum InputMessageContent {
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
// use serde::Deserialize;
|
||||
|
||||
use crate::core::types::{
|
||||
Animation, Audio, Chat, Contact,
|
||||
Document, Game, Invoice, InlineKeyboardMarkup,
|
||||
PhotoSize, MessageEntity, Location, PassportData, Poll,
|
||||
Sticker, SuccessfulPayment,
|
||||
User, Video, VideoNote, Venue, Voice,
|
||||
Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup, Invoice, Location,
|
||||
MessageEntity, PassportData, PhotoSize, Poll, Sticker, SuccessfulPayment, User, Venue, Video,
|
||||
VideoNote, Voice,
|
||||
};
|
||||
|
||||
#[derive(Debug, Deserialize, Hash, PartialEq, Eq)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::core::types::User;
|
||||
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Hash, Eq)]
|
||||
pub struct MessageEntity {
|
||||
#[serde(flatten)]
|
||||
|
@ -13,10 +12,19 @@ pub struct MessageEntity {
|
|||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "type")]
|
||||
pub enum MessageEntityKind {
|
||||
Mention, Hashtag, Cashtag, BotCommand, Url, Email, PhoneNumber,
|
||||
Bold, Italic, Code, Pre,
|
||||
Mention,
|
||||
Hashtag,
|
||||
Cashtag,
|
||||
BotCommand,
|
||||
Url,
|
||||
Email,
|
||||
PhoneNumber,
|
||||
Bold,
|
||||
Italic,
|
||||
Code,
|
||||
Pre,
|
||||
TextLink { url: String },
|
||||
TextMention { user: User }
|
||||
TextMention { user: User },
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -25,12 +33,13 @@ fn recursive_kind() {
|
|||
|
||||
assert_eq!(
|
||||
MessageEntity {
|
||||
kind: MessageEntityKind::TextLink { url: "ya.ru".into() },
|
||||
kind: MessageEntityKind::TextLink {
|
||||
url: "ya.ru".into()
|
||||
},
|
||||
offset: 1,
|
||||
length: 2
|
||||
},
|
||||
from_str::<MessageEntity>(
|
||||
r#"{"type":"text_link","url":"ya.ru","offset":1,"length":2}"#
|
||||
).unwrap()
|
||||
from_str::<MessageEntity>(r#"{"type":"text_link","url":"ya.ru","offset":1,"length":2}"#)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,26 +1,11 @@
|
|||
mod not_implemented_types;
|
||||
use self::not_implemented_types::*;
|
||||
|
||||
|
||||
pub use self::{
|
||||
answer_pre_checkout_query::AnswerPreCheckoutQuery,
|
||||
answer_shipping_query::AnswerShippingQuery,
|
||||
chat::Chat,
|
||||
chat_permissions::ChatPermissions,
|
||||
chat_photo::ChatPhoto,
|
||||
document::Document,
|
||||
invoice::Invoice,
|
||||
label_price::LabeledPrice,
|
||||
message::Message,
|
||||
message_entity::MessageEntity,
|
||||
order_info::OrderInfo,
|
||||
pre_checkout_query::PreCheckoutQuery,
|
||||
send_invoice::SendInvoice,
|
||||
shipping_address::ShippingAddress,
|
||||
shipping_option::ShippingOption,
|
||||
shipping_query::ShippingQuery,
|
||||
sticker::Sticker,
|
||||
successful_payment::SuccessfulPayment,
|
||||
answer_pre_checkout_query::AnswerPreCheckoutQuery, answer_shipping_query::AnswerShippingQuery,
|
||||
chat::Chat, chat_permissions::ChatPermissions, chat_photo::ChatPhoto, document::Document,
|
||||
invoice::Invoice, label_price::LabeledPrice, message::Message, message_entity::MessageEntity,
|
||||
order_info::OrderInfo, pre_checkout_query::PreCheckoutQuery, send_invoice::SendInvoice,
|
||||
shipping_address::ShippingAddress, shipping_option::ShippingOption,
|
||||
shipping_query::ShippingQuery, sticker::Sticker, successful_payment::SuccessfulPayment,
|
||||
user::User,
|
||||
input_file::InputFile,
|
||||
input_media::InputMedia,
|
||||
|
@ -37,6 +22,7 @@ mod invoice;
|
|||
mod label_price;
|
||||
mod message;
|
||||
mod message_entity;
|
||||
mod not_implemented_types;
|
||||
mod order_info;
|
||||
mod pre_checkout_query;
|
||||
mod send_invoice;
|
||||
|
|
|
@ -5,4 +5,4 @@ extern crate serde;
|
|||
#[macro_use]
|
||||
extern crate typed_builder;
|
||||
|
||||
mod core;
|
||||
pub mod core;
|
||||
|
|
Loading…
Reference in a new issue