Merge pull request #28 from async-telegram-bot/reformatting

Reformatting
This commit is contained in:
Temirkhan Myrzamadi 2019-09-21 04:14:50 +06:00 committed by GitHub
commit e7edb29fc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
111 changed files with 663 additions and 633 deletions

116
src/bot/api.rs Normal file
View file

@ -0,0 +1,116 @@
use crate::{
bot::Bot,
requests::{
edit_message_live_location::EditMessageLiveLocation,
forward_message::ForwardMessage, get_file::GetFile, get_me::GetMe,
send_audio::SendAudio, send_location::SendLocation,
send_media_group::SendMediaGroup, send_message::SendMessage,
send_photo::SendPhoto,
stop_message_live_location::StopMessageLiveLocation, ChatId,
},
types::{InputFile, InputMedia},
};
/// Telegram functions
impl Bot {
pub fn get_me(&self) -> GetMe {
GetMe::new(self.ctx())
}
pub fn send_message<C, T>(&self, chat_id: C, text: T) -> SendMessage
where
C: Into<ChatId>,
T: Into<String>,
{
SendMessage::new(self.ctx(), chat_id.into(), text.into())
}
pub fn edit_message_live_location<Lt, Lg>(
&self,
latitude: Lt,
longitude: Lg,
) -> EditMessageLiveLocation
where
Lt: Into<f64>,
Lg: Into<f64>,
{
EditMessageLiveLocation::new(
self.ctx(),
latitude.into(),
longitude.into(),
)
}
pub fn forward_message<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_id: M,
) -> ForwardMessage
where
C: Into<ChatId>,
F: Into<ChatId>,
M: Into<i32>,
{
ForwardMessage::new(
self.ctx(),
chat_id.into(),
from_chat_id.into(),
message_id.into(),
)
}
pub fn send_audio<C, A>(&self, chat_id: C, audio: A) -> SendAudio
where
C: Into<ChatId>,
A: Into<InputFile>,
{
SendAudio::new(self.ctx(), chat_id.into(), audio.into())
}
pub fn send_location<C, Lt, Lg>(
&self,
chat_id: C,
latitude: Lt,
longitude: Lg,
) -> SendLocation
where
C: Into<ChatId>,
Lt: Into<f64>,
Lg: Into<f64>,
{
SendLocation::new(
self.ctx(),
chat_id.into(),
latitude.into(),
longitude.into(),
)
}
pub fn send_media_group<C, M>(&self, chat_id: C, media: M) -> SendMediaGroup
where
C: Into<ChatId>,
M: Into<Vec<InputMedia>>,
{
SendMediaGroup::new(self.ctx(), chat_id.into(), media.into())
}
pub fn send_photo<C, P>(&self, chat_id: C, photo: P) -> SendPhoto
where
C: Into<ChatId>,
P: Into<InputFile>,
{
SendPhoto::new(self.ctx(), chat_id.into(), photo.into())
}
pub fn stop_message_live_location(&self) -> StopMessageLiveLocation {
StopMessageLiveLocation::new(self.ctx())
}
pub fn get_file<F>(&self, file_id: F) -> GetFile
where
F: Into<String>,
{
GetFile::new(self.ctx(), file_id.into())
}
}

65
src/bot/download.rs Normal file
View file

@ -0,0 +1,65 @@
use reqwest::r#async::Chunk;
use tokio::{io::AsyncWrite, stream::Stream};
use crate::{
bot::Bot,
network::{download_file, download_file_stream},
DownloadError,
};
impl Bot {
/// Download file from telegram into `destination`.
/// `path` can be obtained from [`get_file`] method.
///
/// For downloading as Stream of Chunks see [`download_file_stream`].
///
/// ## Examples
///
/// ```no_run
/// use async_telegram_bot::{
/// bot::Bot, requests::Request, types::File as TgFile,
/// };
/// use tokio::fs::File;
/// # use async_telegram_bot::RequestError;
///
/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
/// let bot = Bot::new("TOKEN");
/// let mut file = File::create("/home/waffle/Pictures/test.png").await?;
///
/// let TgFile { file_path, .. } = bot.get_file("*file_id*").send().await?;
/// bot.download_file(&file_path, &mut file).await?;
/// # Ok(()) }
/// ```
///
/// [`get_file`]: crate::bot::Bot::get_file
/// [`download_file_stream`]: crate::bot::Bot::download_file_stream
pub async fn download_file<D>(
&self,
path: &str,
destination: &mut D,
) -> Result<(), DownloadError>
where
D: AsyncWrite + Unpin,
{
download_file(&self.client, &self.token, path, destination).await
}
/// Download file from telegram.
///
/// `path` can be obtained from [`get_file`] method.
///
/// For downloading into [`AsyncWrite`] (e.g. [`tokio::fs::File`])
/// see [`download_file`].
///
/// [`get_file`]: crate::bot::Bot::get_file
/// [`AsyncWrite`]: tokio::io::AsyncWrite
/// [`tokio::fs::File`]: tokio::fs::File
/// [`download_file`]: crate::bot::Bot::download_file
pub async fn download_file_stream(
&self,
path: &str,
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error>
{
download_file_stream(&self.client, &self.token, path).await
}
}

View file

@ -1,28 +1,16 @@
mod api;
mod download;
use reqwest::r#async::Client; use reqwest::r#async::Client;
use crate::core::network::{download_file, download_file_stream}; use crate::requests::RequestContext;
use crate::core::requests::get_file::GetFile;
use crate::core::{
requests::{
edit_message_live_location::EditMessageLiveLocation,
forward_message::ForwardMessage, get_me::GetMe, send_audio::SendAudio,
send_location::SendLocation, send_media_group::SendMediaGroup,
send_message::SendMessage, send_photo::SendPhoto,
stop_message_live_location::StopMessageLiveLocation, ChatId,
RequestContext,
},
types::{InputFile, InputMedia},
};
use crate::DownloadError;
use reqwest::r#async::Chunk;
use tokio::io::AsyncWrite;
use tokio::stream::Stream;
pub struct Bot { pub struct Bot {
token: String, token: String,
client: Client, client: Client,
} }
/// Constructors
impl Bot { impl Bot {
pub fn new(token: &str) -> Self { pub fn new(token: &str) -> Self {
Bot { Bot {
@ -37,7 +25,9 @@ impl Bot {
client, client,
} }
} }
}
impl Bot {
fn ctx(&self) -> RequestContext { fn ctx(&self) -> RequestContext {
RequestContext { RequestContext {
token: &self.token, token: &self.token,
@ -45,163 +35,3 @@ impl Bot {
} }
} }
} }
/// Telegram functions
impl Bot {
/// Download file from telegram into `destination`.
/// `path` can be obtained from [`get_file`] method.
///
/// For downloading as Stream of Chunks see [`download_file_stream`].
///
/// ## Examples
///
/// ```no_run
/// use async_telegram_bot::{
/// bot::Bot,
/// core::{requests::Request, types::File as TgFile},
/// };
/// use tokio::fs::File;
/// # use async_telegram_bot::core::requests::RequestError;
///
/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
/// let bot = Bot::new("TOKEN");
/// let mut file = File::create("/home/waffle/Pictures/test.png").await?;
///
/// let TgFile { file_path, .. } = bot.get_file("*file_id*").send().await?;
/// bot.download_file(&file_path, &mut file).await?;
/// # Ok(()) }
/// ```
///
/// [`get_file`]: crate::bot::Bot::get_file
/// [`download_file_stream`]: crate::bot::Bot::download_file_stream
pub async fn download_file<D>(
&self,
path: &str,
destination: &mut D,
) -> Result<(), DownloadError>
where
D: AsyncWrite + Unpin,
{
download_file(&self.client, &self.token, path, destination).await
}
/// Download file from telegram.
///
/// `path` can be obtained from [`get_file`] method.
///
/// For downloading into [`AsyncWrite`] (e.g. [`tokio::fs::File`])
/// see [`download_file`].
///
/// [`get_file`]: crate::bot::Bot::get_file
/// [`AsyncWrite`]: tokio::io::AsyncWrite
/// [`tokio::fs::File`]: tokio::fs::File
/// [`download_file`]: crate::bot::Bot::download_file
pub async fn download_file_stream(
&self,
path: &str,
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error>
{
download_file_stream(&self.client, &self.token, path).await
}
pub fn get_me(&self) -> GetMe {
GetMe::new(self.ctx())
}
pub fn send_message<C, T>(&self, chat_id: C, text: T) -> SendMessage
where
C: Into<ChatId>,
T: Into<String>,
{
SendMessage::new(self.ctx(), chat_id.into(), text.into())
}
pub fn edit_message_live_location<Lt, Lg>(
&self,
latitude: Lt,
longitude: Lg,
) -> EditMessageLiveLocation
where
Lt: Into<f64>,
Lg: Into<f64>,
{
EditMessageLiveLocation::new(
self.ctx(),
latitude.into(),
longitude.into(),
)
}
pub fn forward_message<C, F, M>(
&self,
chat_id: C,
from_chat_id: F,
message_id: M,
) -> ForwardMessage
where
C: Into<ChatId>,
F: Into<ChatId>,
M: Into<i32>,
{
ForwardMessage::new(
self.ctx(),
chat_id.into(),
from_chat_id.into(),
message_id.into(),
)
}
pub fn send_audio<C, A>(&self, chat_id: C, audio: A) -> SendAudio
where
C: Into<ChatId>,
A: Into<InputFile>,
{
SendAudio::new(self.ctx(), chat_id.into(), audio.into())
}
pub fn send_location<C, Lt, Lg>(
&self,
chat_id: C,
latitude: Lt,
longitude: Lg,
) -> SendLocation
where
C: Into<ChatId>,
Lt: Into<f64>,
Lg: Into<f64>,
{
SendLocation::new(
self.ctx(),
chat_id.into(),
latitude.into(),
longitude.into(),
)
}
pub fn send_media_group<C, M>(&self, chat_id: C, media: M) -> SendMediaGroup
where
C: Into<ChatId>,
M: Into<Vec<InputMedia>>,
{
SendMediaGroup::new(self.ctx(), chat_id.into(), media.into())
}
pub fn send_photo<C, P>(&self, chat_id: C, photo: P) -> SendPhoto
where
C: Into<ChatId>,
P: Into<InputFile>,
{
SendPhoto::new(self.ctx(), chat_id.into(), photo.into())
}
pub fn stop_message_live_location(&self) -> StopMessageLiveLocation {
StopMessageLiveLocation::new(self.ctx())
}
pub fn get_file<F>(&self, file_id: F) -> GetFile
where
F: Into<String>,
{
GetFile::new(self.ctx(), file_id.into())
}
}

View file

@ -1,3 +0,0 @@
pub(crate) mod network;
pub mod requests;
pub mod types;

View file

@ -1,204 +0,0 @@
use crate::core::{
requests::{RequestError, ResponseResult},
types::ResponseParameters,
};
use crate::DownloadError;
use apply::Apply;
use bytes::Buf;
use futures::StreamExt;
use reqwest::r#async::Chunk;
use reqwest::{
r#async::{multipart::Form, Client, Response},
StatusCode,
};
use serde::{de::DeserializeOwned, Serialize};
use tokio::io::AsyncWriteExt;
use tokio::prelude::AsyncWrite;
use tokio::stream::Stream;
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
/// 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}",
url = base,
token = token,
method = method_name,
)
}
/// 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}",
url = base,
token = token,
file = file_path,
)
}
pub async fn request_multipart<T: DeserializeOwned>(
client: &Client,
token: &str,
method_name: &str,
params: Option<Form>,
) -> ResponseResult<T> {
process_response(
client
.post(&method_url(TELEGRAM_API_URL, token, method_name))
.apply(|request_builder| match params {
Some(params) => request_builder.multipart(params),
None => request_builder,
})
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
}
pub async fn request_json<T: DeserializeOwned, P: Serialize>(
client: &Client,
token: &str,
method_name: &str,
params: &P,
) -> ResponseResult<T> {
process_response(
client
.post(&method_url(TELEGRAM_API_URL, token, method_name))
.json(params)
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
}
async fn process_response<T: DeserializeOwned>(
mut response: Response,
) -> ResponseResult<T> {
let response = serde_json::from_str::<TelegramResponse<T>>(
&response.text().await.map_err(RequestError::NetworkError)?,
)
.map_err(RequestError::InvalidJson)?;
response.into()
}
#[derive(Deserialize)]
#[serde(untagged)]
enum TelegramResponse<R> {
Ok {
/// A dummy field. Used only for deserialization.
#[allow(dead_code)]
ok: bool, // TODO: True type
result: R,
},
Err {
/// A dummy field. Used only for deserialization.
#[allow(dead_code)]
ok: bool, // TODO: False type
description: String,
error_code: u16,
response_parameters: Option<ResponseParameters>,
},
}
pub async fn download_file<D>(
client: &Client,
token: &str,
path: &str,
destination: &mut D,
) -> Result<(), DownloadError>
where
D: AsyncWrite + Unpin,
{
let mut stream = download_file_stream(client, token, path).await?;
while let Some(chunk) = stream.next().await {
destination.write_all(chunk?.bytes()).await?;
}
Ok(())
}
pub(crate) async fn download_file_stream(
client: &Client,
token: &str,
path: &str,
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error> {
let url = file_url(TELEGRAM_API_URL, token, path);
let resp = client.get(&url).send().await?.error_for_status()?;
Ok(resp.into_body())
}
impl<R> Into<ResponseResult<R>> for TelegramResponse<R> {
fn into(self) -> Result<R, RequestError> {
match self {
TelegramResponse::Ok { result, .. } => Ok(result),
TelegramResponse::Err {
description,
error_code,
response_parameters,
..
} => {
if let Some(params) = response_parameters {
match params {
ResponseParameters::RetryAfter(i) => {
Err(RequestError::RetryAfter(i))
}
ResponseParameters::MigrateToChatId(to) => {
Err(RequestError::MigrateToChatId(to))
}
}
} else {
Err(RequestError::ApiError {
description,
status_code: StatusCode::from_u16(error_code).unwrap(),
})
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn method_url_test() {
let url = method_url(
TELEGRAM_API_URL,
"535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
"methodName",
);
assert_eq!(
url,
"https://api.telegram.org/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/methodName"
);
}
#[test]
fn file_url_test() {
let url = file_url(
TELEGRAM_API_URL,
"535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
"AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ",
);
assert_eq!(
url,
"https://api.telegram.org/file/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ"
);
}
}

View file

@ -1,3 +1,6 @@
use reqwest::StatusCode;
//<editor-fold desc="download">
#[derive(Debug, Display, From)] #[derive(Debug, Display, From)]
pub enum DownloadError { pub enum DownloadError {
#[display(fmt = "Network error: {err}", err = _0)] #[display(fmt = "Network error: {err}", err = _0)]
@ -15,3 +18,43 @@ impl std::error::Error for DownloadError {
} }
} }
} }
//</editor-fold>
//<editor-fold desc="request">
#[derive(Debug, Display)]
pub enum RequestError {
#[display(fmt = "Telegram error #{}: {}", status_code, description)]
ApiError {
status_code: StatusCode,
description: String,
},
/// The group has been migrated to a supergroup with the specified
/// identifier.
#[display(fmt = "The group has been migrated to a supergroup with id {id}", id = _0)]
MigrateToChatId(i64),
/// In case of exceeding flood control, the number of seconds left to wait
/// before the request can be repeated
#[display(fmt = "Retry after {secs} seconds", secs = _0)]
RetryAfter(i32),
#[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::MigrateToChatId(_) => None,
RequestError::RetryAfter(_) => None,
RequestError::NetworkError(err) => Some(err),
RequestError::InvalidJson(err) => Some(err),
}
}
}
//</editor-fold>

View file

@ -3,8 +3,11 @@ extern crate derive_more;
#[macro_use] #[macro_use]
extern crate serde; extern crate serde;
pub mod bot; mod network;
pub mod core;
pub mod errors;
pub use errors::DownloadError; pub mod bot;
pub mod errors;
pub mod requests;
pub mod types;
pub use errors::{DownloadError, RequestError};

40
src/network/download.rs Normal file
View file

@ -0,0 +1,40 @@
use futures::StreamExt;
use reqwest::r#async::{Chunk, Client};
use tokio::{
io::{AsyncWrite, AsyncWriteExt},
stream::Stream,
};
use bytes::Buf;
use crate::{
network::{file_url, TELEGRAM_API_URL},
DownloadError,
};
pub async fn download_file<D>(
client: &Client,
token: &str,
path: &str,
destination: &mut D,
) -> Result<(), DownloadError>
where
D: AsyncWrite + Unpin,
{
let mut stream = download_file_stream(client, token, path).await?;
while let Some(chunk) = stream.next().await {
destination.write_all(chunk?.bytes()).await?;
}
Ok(())
}
pub async fn download_file_stream(
client: &Client,
token: &str,
path: &str,
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error> {
let url = file_url(TELEGRAM_API_URL, token, path);
let resp = client.get(&url).send().await?.error_for_status()?;
Ok(resp.into_body())
}

66
src/network/mod.rs Normal file
View file

@ -0,0 +1,66 @@
mod download;
mod request;
mod telegram_response;
pub use download::{download_file, download_file_stream};
pub use request::{request_json, request_multipart};
pub use telegram_response::TelegramResponse;
pub const TELEGRAM_API_URL: &str = "https://api.telegram.org";
/// 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}",
url = base,
token = token,
method = method_name,
)
}
/// 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}",
url = base,
token = token,
file = file_path,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn method_url_test() {
let url = method_url(
TELEGRAM_API_URL,
"535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
"methodName",
);
assert_eq!(
url,
"https://api.telegram.org/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/methodName"
);
}
#[test]
fn file_url_test() {
let url = file_url(
TELEGRAM_API_URL,
"535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao",
"AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ",
);
assert_eq!(
url,
"https://api.telegram.org/file/bot535362388:AAF7-g0gYncWnm5IyfZlpPRqRRv6kNAGlao/AgADAgADyqoxG2g8aEsu_KjjVsGF4-zetw8ABAEAAwIAA20AA_8QAwABFgQ"
);
}
}

60
src/network/request.rs Normal file
View file

@ -0,0 +1,60 @@
use apply::Apply;
use reqwest::r#async::{multipart::Form, Client, Response};
use serde::{de::DeserializeOwned, Serialize};
use crate::{
network::{method_url, TELEGRAM_API_URL, TelegramResponse},
requests::ResponseResult,
RequestError,
};
pub async fn request_multipart<T>(
client: &Client,
token: &str,
method_name: &str,
params: Option<Form>,
) -> ResponseResult<T>
where
T: DeserializeOwned,
{
process_response(
client
.post(&method_url(TELEGRAM_API_URL, token, method_name))
.apply(|request_builder| match params {
Some(params) => request_builder.multipart(params),
None => request_builder,
})
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
}
pub async fn request_json<T: DeserializeOwned, P: Serialize>(
client: &Client,
token: &str,
method_name: &str,
params: &P,
) -> ResponseResult<T> {
process_response(
client
.post(&method_url(TELEGRAM_API_URL, token, method_name))
.json(params)
.send()
.await
.map_err(RequestError::NetworkError)?,
)
.await
}
async fn process_response<T: DeserializeOwned>(
mut response: Response,
) -> ResponseResult<T> {
let response = serde_json::from_str::<TelegramResponse<T>>(
&response.text().await.map_err(RequestError::NetworkError)?,
)
.map_err(RequestError::InvalidJson)?;
response.into()
}

View file

@ -0,0 +1,56 @@
use reqwest::StatusCode;
use crate::{
requests::ResponseResult, types::ResponseParameters, RequestError,
};
#[derive(Deserialize)]
#[serde(untagged)]
pub enum TelegramResponse<R> {
Ok {
/// A dummy field. Used only for deserialization.
#[allow(dead_code)]
ok: bool, // TODO: True type
result: R,
},
Err {
/// A dummy field. Used only for deserialization.
#[allow(dead_code)]
ok: bool, // TODO: False type
description: String,
error_code: u16,
response_parameters: Option<ResponseParameters>,
},
}
impl<R> Into<ResponseResult<R>> for TelegramResponse<R> {
fn into(self) -> Result<R, RequestError> {
match self {
TelegramResponse::Ok { result, .. } => Ok(result),
TelegramResponse::Err {
description,
error_code,
response_parameters,
..
} => {
if let Some(params) = response_parameters {
match params {
ResponseParameters::RetryAfter(i) => {
Err(RequestError::RetryAfter(i))
}
ResponseParameters::MigrateToChatId(to) => {
Err(RequestError::MigrateToChatId(to))
}
}
} else {
Err(RequestError::ApiError {
description,
status_code: StatusCode::from_u16(error_code).unwrap(),
})
}
}
}
}
}

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{Request, RequestContext, RequestFuture, ResponseResult}, requests::{Request, RequestContext, RequestFuture, ResponseResult},
}; };

View file

@ -1,8 +1,8 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
Request, RequestContext, RequestFuture, ResponseResult, requests::{Request, RequestContext, RequestFuture, ResponseResult},
types::ShippingOption,
}; };
use crate::core::types::ShippingOption;
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
/// If you sent an invoice requesting a shipping address and the parameter /// If you sent an invoice requesting a shipping address and the parameter

View file

@ -1,9 +1,10 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
ChatId, Request, RequestContext, RequestFuture, ResponseResult, requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
types::{Message, ReplyMarkup},
}; };
use crate::core::types::{Message, ReplyMarkup};
use serde::Serialize;
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
/// Use this method to edit live location messages. A location can be edited /// Use this method to edit live location messages. A location can be edited

View file

@ -1,12 +1,12 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::core::{ use reqwest::r#async::multipart::Form;
use crate::{
requests::{utils, ChatId}, requests::{utils, ChatId},
types::{InputMedia, ParseMode}, types::{InputMedia, ParseMode},
}; };
use reqwest::r#async::multipart::Form;
/// This is a convenient struct that builds `reqwest::r#async::multipart::Form` /// This is a convenient struct that builds `reqwest::r#async::multipart::Form`
/// from scratch. /// from scratch.
pub struct FormBuilder { pub struct FormBuilder {

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{ requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult, ChatId, Request, RequestContext, RequestFuture, ResponseResult,

View file

@ -1,21 +1,24 @@
use crate::core::requests::{ChatId, RequestContext, RequestFuture, ResponseResult, Request}; use crate::{
use crate::core::types::Chat; network,
use crate::core::network; requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
types::Chat,
};
/// Use this method to get up to date information about the chat /// Use this method to get up to date information about the chat
/// (current name of the user for one-on-one conversations, /// (current name of the user for one-on-one conversations,
/// current username of a user, group or channel, etc.). /// current username of a user, group or channel, etc.).
/// Returns a Chat object on success. /// Returns a Chat object on success.
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct GetChat<'a> { pub struct GetChat<'a> {
#[serde(skip_serializing)] #[serde(skip_serializing)]
ctx: RequestContext<'a>, ctx: RequestContext<'a>,
/// Unique identifier for the target chat or username /// Unique identifier for the target chat or username
/// of the target supergroup or channel (in the format @channelusername) /// of the target supergroup or channel (in the format @channelusername)
chat_id: ChatId, chat_id: ChatId,
} }
impl<'a> Request<'a> for GetChat<'a> { impl<'a> Request<'a> for GetChat<'a> {
type ReturnValue = Chat; type ReturnValue = Chat;
@ -26,16 +29,16 @@ impl<'a> Request<'a> for GetChat<'a> {
&self.ctx.token, &self.ctx.token,
"getChat", "getChat",
&self, &self,
).await )
.await
}) })
} }
} }
impl<'a> GetChat<'a> {
impl<'a> GetChat<'a>{
pub fn chat_id<T>(mut self, chat_id: T) -> Self pub fn chat_id<T>(mut self, chat_id: T) -> Self
where where
T: Into<ChatId>, T: Into<ChatId>,
{ {
self.chat_id = chat_id.into(); self.chat_id = chat_id.into();
self self

View file

@ -1,8 +1,8 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
Request, RequestContext, RequestFuture, ResponseResult, requests::{Request, RequestContext, RequestFuture, ResponseResult},
types::File,
}; };
use crate::core::types::File;
/// Use this method to get basic info about a file and prepare it for /// Use this method to get basic info about a file and prepare it for
/// downloading. For the moment, bots can download files of up to 20MB in size. /// downloading. For the moment, bots can download files of up to 20MB in size.

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{Request, RequestContext, RequestFuture, ResponseResult}, requests::{Request, RequestContext, RequestFuture, ResponseResult},
types::User, types::User,

View file

@ -1,4 +1,4 @@
use crate::core::requests::RequestContext; use crate::requests::RequestContext;
//TODO: complete implementation after user_profile_fotos will be added to //TODO: complete implementation after user_profile_fotos will be added to
// types/mod.rs // types/mod.rs

View file

@ -1,4 +1,4 @@
use crate::core::requests::RequestContext; use crate::requests::RequestContext;
//TODO:: need implementation //TODO:: need implementation
/// Use this method to kick a user from a group, a supergroup or a channel. In /// Use this method to kick a user from a group, a supergroup or a channel. In
/// the case of supergroups and channels, the user will not be able to return to /// the case of supergroups and channels, the user will not be able to return to

View file

@ -1,48 +1,11 @@
use std::future::Future;
use std::pin::Pin;
use reqwest::{r#async::Client, StatusCode};
use serde::de::DeserializeOwned;
mod form_builder; mod form_builder;
mod utils; mod utils;
#[derive(Debug, Display)] use reqwest::r#async::Client;
pub enum RequestError { use serde::de::DeserializeOwned;
#[display(fmt = "Telegram error #{}: {}", status_code, description)] use std::{future::Future, pin::Pin};
ApiError {
status_code: StatusCode,
description: String,
},
/// The group has been migrated to a supergroup with the specified use crate::RequestError;
/// identifier.
#[display(fmt = "The group has been migrated to a supergroup with id {id}", id = _0)]
MigrateToChatId(i64),
/// In case of exceeding flood control, the number of seconds left to wait
/// before the request can be repeated
#[display(fmt = "Retry after {secs} seconds", secs = _0)]
RetryAfter(i32),
#[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::MigrateToChatId(_) => None,
RequestError::RetryAfter(_) => None,
RequestError::NetworkError(err) => Some(err),
RequestError::InvalidJson(err) => Some(err),
}
}
}
pub type ResponseResult<T> = Result<T, RequestError>; pub type ResponseResult<T> = Result<T, RequestError>;
@ -104,6 +67,7 @@ pub mod answer_pre_checkout_query;
pub mod answer_shipping_query; pub mod answer_shipping_query;
pub mod edit_message_live_location; pub mod edit_message_live_location;
pub mod forward_message; pub mod forward_message;
pub mod get_chat;
pub mod get_file; pub mod get_file;
pub mod get_me; pub mod get_me;
pub mod get_user_profile_photos; pub mod get_user_profile_photos;

View file

@ -1,4 +1,4 @@
use crate::core::requests::RequestContext; use crate::requests::RequestContext;
//TODO:: need implementation //TODO:: need implementation
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]

View file

@ -1,8 +1,8 @@
use crate::core::{ use crate::{
network, network,
requests::form_builder::FormBuilder,
requests::{ requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult, form_builder::FormBuilder, ChatId, Request, RequestContext,
RequestFuture, ResponseResult,
}, },
types::{InputFile, Message, ParseMode, ReplyMarkup}, types::{InputFile, Message, ParseMode, ReplyMarkup},
}; };
@ -32,10 +32,10 @@ pub struct SendAudio<'a> {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
pub parse_mode: Option<ParseMode>, pub parse_mode: Option<ParseMode>,
/// Duration of the audio in seconds /// Duration of the audio in seconds
pub duration: Option<i32>, pub duration: Option<i32>,

View file

@ -1,6 +1,8 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
ChatId, Request, RequestContext, RequestFuture, ResponseResult, requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
}; };
///Use this method when you need to tell the user that something is happening ///Use this method when you need to tell the user that something is happening

View file

@ -1,8 +1,10 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
ChatId, Request, RequestContext, RequestFuture, ResponseResult, requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
types::{Message, ReplyMarkup},
}; };
use crate::core::types::{Message, ReplyMarkup};
/// Use this method to send phone contacts. /// Use this method to send phone contacts.
/// returned. /// returned.

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{ requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult, ChatId, Request, RequestContext, RequestFuture, ResponseResult,

View file

@ -1,4 +1,6 @@
use crate::core::{ use apply::Apply;
use crate::{
network::request_multipart, network::request_multipart,
requests::{ requests::{
form_builder::FormBuilder, ChatId, Request, RequestContext, form_builder::FormBuilder, ChatId, Request, RequestContext,
@ -6,7 +8,6 @@ use crate::core::{
}, },
types::{InputFile, InputMedia, Message}, types::{InputFile, InputMedia, Message},
}; };
use apply::Apply;
/// Use this method to send a group of photos or videos as an album. /// Use this method to send a group of photos or videos as an album.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{ requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult, ChatId, Request, RequestContext, RequestFuture, ResponseResult,
@ -23,10 +23,10 @@ pub struct SendMessage<'a> {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub parse_mode: Option<ParseMode>, pub parse_mode: Option<ParseMode>,
/// Disables link previews for links in this message /// Disables link previews for links in this message

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{ requests::{
form_builder::FormBuilder, ChatId, Request, RequestContext, form_builder::FormBuilder, ChatId, Request, RequestContext,
@ -30,10 +30,10 @@ pub struct SendPhoto<'a> {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
pub parse_mode: Option<ParseMode>, pub parse_mode: Option<ParseMode>,
/// Sends the message silently. Users will receive a notification with no /// Sends the message silently. Users will receive a notification with no
/// sound. /// sound.

View file

@ -1,8 +1,10 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
ChatId, Request, RequestContext, RequestFuture, ResponseResult, requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
types::{Message, ReplyMarkup},
}; };
use crate::core::types::{Message, ReplyMarkup};
/// Use this method to send a native poll. A native poll can't be sent to a /// Use this method to send a native poll. A native poll can't be sent to a
/// private chat. On success, the sent Message is returned. /// private chat. On success, the sent Message is returned.

View file

@ -1,8 +1,10 @@
use crate::core::network; use crate::{
use crate::core::requests::{ network,
ChatId, Request, RequestContext, RequestFuture, ResponseResult, requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
},
types::{Message, ReplyMarkup},
}; };
use crate::core::types::{Message, ReplyMarkup};
/// Use this method to send information about a venue. /// Use this method to send information about a venue.
/// Message is returned. /// Message is returned.

View file

@ -1,4 +1,4 @@
use crate::core::{ use crate::{
network, network,
requests::{ requests::{
ChatId, Request, RequestContext, RequestFuture, ResponseResult, ChatId, Request, RequestContext, RequestFuture, ResponseResult,

View file

@ -1,4 +1,4 @@
use crate::core::requests::RequestContext; use crate::requests::RequestContext;
//TODO:: need implementation //TODO:: need implementation
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]

View file

@ -1,4 +1,4 @@
use crate::core::types::PhotoSize; use crate::types::PhotoSize;
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
/// This object represents an animation file (GIF or H.264/MPEG-4 AVC video /// This object represents an animation file (GIF or H.264/MPEG-4 AVC video

View file

@ -1,4 +1,4 @@
use crate::core::types::PhotoSize; use crate::types::PhotoSize;
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone)]
pub struct Audio { pub struct Audio {
@ -42,8 +42,8 @@ mod tests {
file_id: "id".to_string(), file_id: "id".to_string(),
width: 320, width: 320,
height: 320, height: 320,
file_size: Some(3452) file_size: Some(3452),
}) }),
}; };
let actual = serde_json::from_str::<Audio>(&json).unwrap(); let actual = serde_json::from_str::<Audio>(&json).unwrap();
assert_eq!(actual, expected) assert_eq!(actual, expected)

View file

@ -1,2 +1,2 @@
/// A placeholder, currently holds no information. Use [BotFather](https://t.me/botfather) to set up your game. /// A placeholder, currently holds no information. Use [BotFather](https://t.me/botfather) to set up your game.
pub struct CallbackGame; pub struct CallbackGame;

View file

@ -1,4 +1,4 @@
use crate::core::types::{Message, User}; use crate::types::{Message, User};
#[derive(Debug, Deserialize, PartialEq, Clone)] #[derive(Debug, Deserialize, PartialEq, Clone)]
pub struct CallbackQuery { pub struct CallbackQuery {
@ -8,7 +8,7 @@ pub struct CallbackQuery {
pub message: Option<Message>, pub message: Option<Message>,
pub inline_message_id: Option<String>, pub inline_message_id: Option<String>,
pub data: Option<String>, pub data: Option<String>,
pub game_short_name: Option<String> pub game_short_name: Option<String>,
} }
#[cfg(test)] #[cfg(test)]
@ -37,13 +37,13 @@ mod tests {
first_name: "firstName".to_string(), first_name: "firstName".to_string(),
last_name: None, last_name: None,
username: None, username: None,
language_code: None language_code: None,
}, },
chat_instance: "123456".to_string(), chat_instance: "123456".to_string(),
message: None, message: None,
inline_message_id: Some("i_m_id".to_string()), inline_message_id: Some("i_m_id".to_string()),
data: Some("some_data".to_string()), data: Some("some_data".to_string()),
game_short_name: Some("game_name".to_string()) game_short_name: Some("game_name".to_string()),
}; };
let actual = serde_json::from_str::<CallbackQuery>(json).unwrap(); let actual = serde_json::from_str::<CallbackQuery>(json).unwrap();
assert_eq!(actual, expected); assert_eq!(actual, expected);

View file

@ -1,4 +1,4 @@
use crate::core::types::{ChatPermissions, ChatPhoto, Message}; use crate::types::{ChatPermissions, ChatPhoto, Message};
#[derive(Debug, Deserialize, PartialEq, Clone)] #[derive(Debug, Deserialize, PartialEq, Clone)]
pub struct Chat { pub struct Chat {
@ -80,7 +80,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::core::types::*; use crate::types::*;
use serde_json::from_str; use serde_json::from_str;
#[test] #[test]

View file

@ -1,4 +1,4 @@
use crate::core::types::User; use crate::types::User;
/// This object contains information about one member of the chat. /// This object contains information about one member of the chat.
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)]
@ -63,7 +63,7 @@ pub enum ChatMemberStatus {
Member, Member,
Restricted, Restricted,
Left, Left,
Kicked Kicked,
} }
#[cfg(test)] #[cfg(test)]
@ -103,7 +103,7 @@ mod tests {
first_name: "firstName".to_string(), first_name: "firstName".to_string(),
last_name: None, last_name: None,
username: None, username: None,
language_code: None language_code: None,
}, },
status: ChatMemberStatus::Creator, status: ChatMemberStatus::Creator,
until_date: Some(123456), until_date: Some(123456),
@ -119,9 +119,9 @@ mod tests {
can_send_messages: Some(true), can_send_messages: Some(true),
can_send_media_messages: Some(true), can_send_media_messages: Some(true),
can_send_other_messages: Some(true), can_send_other_messages: Some(true),
can_add_web_page_previews: Some(true) can_add_web_page_previews: Some(true),
}; };
let actual = serde_json::from_str::<ChatMember>(&json).unwrap(); let actual = serde_json::from_str::<ChatMember>(&json).unwrap();
assert_eq!(actual, expected) assert_eq!(actual, expected)
} }
} }

View file

@ -1,4 +1,4 @@
use crate::core::types::{Location, User}; use crate::types::{Location, User};
#[derive(Debug, Deserialize, Clone, PartialEq)] #[derive(Debug, Deserialize, Clone, PartialEq)]
/// Represents a result of an inline query that was chosen by the user and /// Represents a result of an inline query that was chosen by the user and

View file

@ -1,4 +1,4 @@
use crate::core::types::PhotoSize; use crate::types::PhotoSize;
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone, Serialize)]
pub struct Document { pub struct Document {

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
use crate::core::types::{Animation, MessageEntity, PhotoSize}; use crate::types::{Animation, MessageEntity, PhotoSize};
#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Deserialize, Clone, PartialEq, Eq, Hash)]
/// This object represents a game. Use BotFather to create and edit games, their /// This object represents a game. Use BotFather to create and edit games, their

View file

@ -1,6 +1,6 @@
use serde::Deserialize; use serde::Deserialize;
use crate::core::types::user::User; use crate::types::user::User;
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
/// This object represents one row of the high scores table for a game. /// This object represents one row of the high scores table for a game.
@ -11,4 +11,4 @@ pub struct GameHighScore {
pub user: User, pub user: User,
/// Score /// Score
pub score: u32, pub score: u32,
} }

View file

@ -45,7 +45,7 @@ pub enum InlineKeyboardButtonKind {
/// ///
/// Example: /// Example:
/// ```edition2018 /// ```edition2018
/// use async_telegram_bot::core::types::InlineKeyboardButton; /// use async_telegram_bot::types::InlineKeyboardButton;
/// ///
/// fn main() { /// fn main() {
/// let url_button = InlineKeyboardButton::url( /// let url_button = InlineKeyboardButton::url(

View file

@ -1,4 +1,4 @@
use crate::core::types::InlineKeyboardButton; use crate::types::InlineKeyboardButton;
/// This object represents an inline keyboard that appears right next to the /// This object represents an inline keyboard that appears right next to the
/// message it belongs to. /// message it belongs to.
@ -16,7 +16,7 @@ pub struct InlineKeyboardMarkup {
/// ///
/// Example: /// Example:
/// ``` /// ```
/// use async_telegram_bot::core::types::{ /// use async_telegram_bot::types::{
/// InlineKeyboardButton, InlineKeyboardMarkup, /// InlineKeyboardButton, InlineKeyboardMarkup,
/// }; /// };
/// ///

View file

@ -1,4 +1,4 @@
use crate::core::types::{Location, User}; use crate::types::{Location, User};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQuery { pub struct InlineQuery {

View file

@ -1,4 +1,4 @@
use crate::core::types::{ use crate::types::{
InlineQueryResultArticle, InlineQueryResultAudio, InlineQueryResultArticle, InlineQueryResultAudio,
InlineQueryResultCachedAudio, InlineQueryResultCachedDocument, InlineQueryResultCachedAudio, InlineQueryResultCachedDocument,
InlineQueryResultCachedGif, InlineQueryResultCachedMpeg4Gif, InlineQueryResultCachedGif, InlineQueryResultCachedMpeg4Gif,
@ -49,9 +49,9 @@ pub enum InlineQueryResult {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::core::types::inline_keyboard_markup::InlineKeyboardMarkup; use crate::types::inline_keyboard_markup::InlineKeyboardMarkup;
use crate::core::types::parse_mode::ParseMode; use crate::types::parse_mode::ParseMode;
use crate::core::types::{ use crate::types::{
InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent, InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent,
}; };

View file

@ -1,4 +1,4 @@
use crate::core::types::{InlineKeyboardMarkup, InputMessageContent}; use crate::types::{InlineKeyboardMarkup, InputMessageContent};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultArticle { pub struct InlineQueryResultArticle {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultAudio { pub struct InlineQueryResultAudio {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedAudio { pub struct InlineQueryResultCachedAudio {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedDocument { pub struct InlineQueryResultCachedDocument {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedGif { pub struct InlineQueryResultCachedGif {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedMpeg4Gif { pub struct InlineQueryResultCachedMpeg4Gif {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedPhoto { pub struct InlineQueryResultCachedPhoto {

View file

@ -1,4 +1,4 @@
use crate::core::types::{InlineKeyboardMarkup, InputMessageContent}; use crate::types::{InlineKeyboardMarkup, InputMessageContent};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedSticker { pub struct InlineQueryResultCachedSticker {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedVideo { pub struct InlineQueryResultCachedVideo {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultCachedVoice { pub struct InlineQueryResultCachedVoice {

View file

@ -1,4 +1,4 @@
use crate::core::types::{InlineKeyboardMarkup, InputMessageContent}; use crate::types::{InlineKeyboardMarkup, InputMessageContent};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultContact { pub struct InlineQueryResultContact {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultDocument { pub struct InlineQueryResultDocument {

View file

@ -1,4 +1,4 @@
use crate::core::types::InlineKeyboardMarkup; use crate::types::InlineKeyboardMarkup;
#[derive(Debug, Serialize, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Serialize, Hash, PartialEq, Eq, Clone)]
pub struct InlineQueryResultGame { pub struct InlineQueryResultGame {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultGif { pub struct InlineQueryResultGif {

View file

@ -1,4 +1,4 @@
use crate::core::types::{InlineKeyboardMarkup, InputMessageContent}; use crate::types::{InlineKeyboardMarkup, InputMessageContent};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultLocation { pub struct InlineQueryResultLocation {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultMpeg4Gif { pub struct InlineQueryResultMpeg4Gif {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
/// Represents a link to a photo. By default, this photo will be sent by the /// Represents a link to a photo. By default, this photo will be sent by the
/// user with optional caption. Alternatively, you can use input_message_content /// user with optional caption. Alternatively, you can use input_message_content

View file

@ -1,4 +1,4 @@
use crate::core::types::{InlineKeyboardMarkup, InputMessageContent}; use crate::types::{InlineKeyboardMarkup, InputMessageContent};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultVenue { pub struct InlineQueryResultVenue {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultVideo { pub struct InlineQueryResultVideo {

View file

@ -1,6 +1,4 @@
use crate::core::types::{ use crate::types::{InlineKeyboardMarkup, InputMessageContent, ParseMode};
InlineKeyboardMarkup, InputMessageContent, ParseMode,
};
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
pub struct InlineQueryResultVoice { pub struct InlineQueryResultVoice {

View file

@ -1,4 +1,4 @@
use crate::core::types::{InputFile, ParseMode}; use crate::types::{InputFile, ParseMode};
// TODO: should variants use new-type? // TODO: should variants use new-type?
#[derive(Debug, Serialize, PartialEq, Eq, Clone)] #[derive(Debug, Serialize, PartialEq, Eq, Clone)]
@ -18,10 +18,10 @@ pub enum InputMedia {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>, parse_mode: Option<ParseMode>,
}, },
@ -35,7 +35,7 @@ pub enum InputMedia {
/// size. A thumbnails width and height should not exceed 320. /// size. A thumbnails width and height should not exceed 320.
/// Ignored if the file is not uploaded using [InputFile::File]. /// Ignored if the file is not uploaded using [InputFile::File].
/// ///
/// [InputFile::File]: crate::core::types::InputFile::File /// [InputFile::File]: crate::types::InputFile::File
thumb: Option<InputFile>, thumb: Option<InputFile>,
/// Caption of the video to be sent, 0-1024 characters. /// Caption of the video to be sent, 0-1024 characters.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -44,10 +44,10 @@ pub enum InputMedia {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>, parse_mode: Option<ParseMode>,
/// Video width /// Video width
@ -74,7 +74,7 @@ pub enum InputMedia {
/// size. A thumbnails width and height should not exceed 320. /// size. A thumbnails width and height should not exceed 320.
/// Ignored if the file is not uploaded using [InputFile::File]. /// Ignored if the file is not uploaded using [InputFile::File].
/// ///
/// [InputFile::File]: crate::core::types::InputFile::File /// [InputFile::File]: crate::types::InputFile::File
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>, thumb: Option<InputFile>,
/// Caption of the animation to be sent, 0-1024 characters /// Caption of the animation to be sent, 0-1024 characters
@ -84,10 +84,10 @@ pub enum InputMedia {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>, parse_mode: Option<ParseMode>,
/// Animation width /// Animation width
@ -110,7 +110,7 @@ pub enum InputMedia {
/// size. A thumbnails width and height should not exceed 320. /// size. A thumbnails width and height should not exceed 320.
/// Ignored if the file is not uploaded using [InputFile::File]. /// Ignored if the file is not uploaded using [InputFile::File].
/// ///
/// [InputFile::File]: crate::core::types::InputFile::File /// [InputFile::File]: crate::types::InputFile::File
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>, thumb: Option<InputFile>,
/// Caption of the audio to be sent, 0-1024 characters /// Caption of the audio to be sent, 0-1024 characters
@ -120,10 +120,10 @@ pub enum InputMedia {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<String>, parse_mode: Option<String>,
/// Duration of the audio in seconds /// Duration of the audio in seconds
@ -146,7 +146,7 @@ pub enum InputMedia {
/// size. A thumbnails width and height should not exceed 320. /// size. A thumbnails width and height should not exceed 320.
/// Ignored if the file is not uploaded using [InputFile::File]. /// Ignored if the file is not uploaded using [InputFile::File].
/// ///
/// [InputFile::File]: crate::core::types::InputFile::File /// [InputFile::File]: crate::types::InputFile::File
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
thumb: Option<InputFile>, thumb: Option<InputFile>,
/// Caption of the document to be sent, 0-1024 characters /// Caption of the document to be sent, 0-1024 characters
@ -156,10 +156,10 @@ pub enum InputMedia {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>, parse_mode: Option<ParseMode>,
}, },

View file

@ -1,6 +1,6 @@
use serde::Serialize; use serde::Serialize;
use crate::core::types::ParseMode; use crate::types::ParseMode;
#[derive(Debug, Serialize, Clone, PartialEq)] #[derive(Debug, Serialize, Clone, PartialEq)]
#[serde(untagged)] #[serde(untagged)]
@ -18,10 +18,10 @@ pub enum InputMessageContent {
/// if you want Telegram apps to show [bold, italic, fixed-width text /// if you want Telegram apps to show [bold, italic, fixed-width text
/// or inline URLs] in the media caption. /// or inline URLs] in the media caption.
/// ///
/// [Markdown]: crate::core::types::ParseMode::Markdown /// [Markdown]: crate::types::ParseMode::Markdown
/// [Html]: crate::core::types::ParseMode::Html /// [Html]: crate::types::ParseMode::Html
/// [bold, italic, fixed-width text or inline URLs]: /// [bold, italic, fixed-width text or inline URLs]:
/// crate::core::types::ParseMode /// crate::types::ParseMode
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
parse_mode: Option<ParseMode>, parse_mode: Option<ParseMode>,

View file

@ -7,4 +7,4 @@ pub struct LoginUrl {
pub bot_username: Option<String>, pub bot_username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub request_write_access: Option<bool>, pub request_write_access: Option<bool>,
} }

View file

@ -1,4 +1,4 @@
use crate::core::types::{ use crate::types::{
Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup, Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup,
Invoice, Location, MessageEntity, PassportData, PhotoSize, Poll, Sticker, Invoice, Location, MessageEntity, PassportData, PhotoSize, Poll, Sticker,
SuccessfulPayment, User, Venue, Video, VideoNote, Voice, SuccessfulPayment, User, Venue, Video, VideoNote, Voice,
@ -17,9 +17,10 @@ pub struct Message {
impl Message { impl Message {
fn text(&self) -> Option<&str> { fn text(&self) -> Option<&str> {
if let MessageKind::Common { if let MessageKind::Common {
media_kind: MediaKind::Text { media_kind: MediaKind::Text { ref text, .. },
ref text, .. ..
}, .. } = self.kind { } = self.kind
{
Some(text) Some(text)
} else { } else {
None None
@ -202,7 +203,7 @@ pub enum MediaKind {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::core::types::*; use crate::types::*;
use serde_json::from_str; use serde_json::from_str;
#[test] #[test]

View file

@ -1,4 +1,4 @@
use crate::core::types::User; use crate::types::User;
#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone, Serialize)] #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone, Serialize)]
pub struct MessageEntity { pub struct MessageEntity {

View file

@ -2,6 +2,7 @@ use self::not_implemented_types::*;
pub use self::{ pub use self::{
animation::Animation, animation::Animation,
audio::Audio, audio::Audio,
callback_game::CallbackGame,
callback_query::CallbackQuery, callback_query::CallbackQuery,
chat::{Chat, ChatKind, NonPrivateChatKind}, chat::{Chat, ChatKind, NonPrivateChatKind},
chat_member::{ChatMember, ChatMemberStatus}, chat_member::{ChatMember, ChatMemberStatus},
@ -13,6 +14,7 @@ pub use self::{
file::File, file::File,
force_reply::ForceReply, force_reply::ForceReply,
game::Game, game::Game,
game_high_score::GameHighScore,
inline_keyboard_button::{InlineKeyboardButton, InlineKeyboardButtonKind}, inline_keyboard_button::{InlineKeyboardButton, InlineKeyboardButtonKind},
inline_keyboard_markup::InlineKeyboardMarkup, inline_keyboard_markup::InlineKeyboardMarkup,
inline_query::InlineQuery, inline_query::InlineQuery,
@ -44,6 +46,7 @@ pub use self::{
keyboard_button::KeyboardButton, keyboard_button::KeyboardButton,
label_price::LabeledPrice, label_price::LabeledPrice,
location::Location, location::Location,
login_url::LoginUrl,
mask_position::MaskPosition, mask_position::MaskPosition,
message::{ message::{
ForwardKind, ForwardedFrom, MediaKind, Message, MessageKind, Sender, ForwardKind, ForwardedFrom, MediaKind, Message, MessageKind, Sender,
@ -63,17 +66,21 @@ pub use self::{
shipping_option::ShippingOption, shipping_option::ShippingOption,
shipping_query::ShippingQuery, shipping_query::ShippingQuery,
sticker::Sticker, sticker::Sticker,
sticker_set::StickerSet,
successful_payment::SuccessfulPayment, successful_payment::SuccessfulPayment,
update::{Update, UpdateKind}, update::{Update, UpdateKind},
user::User, user::User,
user_profile_photos::UserProfilePhotos,
venue::Venue, venue::Venue,
video::Video, video::Video,
video_note::VideoNote, video_note::VideoNote,
voice::Voice, voice::Voice,
webhook_info::WebhookInfo,
}; };
mod animation; mod animation;
mod audio; mod audio;
mod callback_game;
mod callback_query; mod callback_query;
mod chat; mod chat;
mod chat_member; mod chat_member;
@ -85,6 +92,7 @@ mod document;
mod file; mod file;
mod force_reply; mod force_reply;
mod game; mod game;
mod game_high_score;
mod inline_keyboard_button; mod inline_keyboard_button;
mod inline_keyboard_markup; mod inline_keyboard_markup;
mod input_file; mod input_file;
@ -94,6 +102,7 @@ mod invoice;
mod keyboard_button; mod keyboard_button;
mod label_price; mod label_price;
mod location; mod location;
mod login_url;
mod mask_position; mod mask_position;
mod message; mod message;
mod message_entity; mod message_entity;
@ -112,13 +121,16 @@ mod shipping_address;
mod shipping_option; mod shipping_option;
mod shipping_query; mod shipping_query;
mod sticker; mod sticker;
mod sticker_set;
mod successful_payment; mod successful_payment;
mod update; mod update;
mod user; mod user;
mod user_profile_photos;
mod venue; mod venue;
mod video; mod video;
mod video_note; mod video_note;
mod voice; mod voice;
mod webhook_info;
mod inline_query; mod inline_query;
mod inline_query_result; mod inline_query_result;

View file

@ -1,4 +1,4 @@
use crate::core::types::ShippingAddress; use crate::types::ShippingAddress;
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone, Serialize)] #[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone, Serialize)]
pub struct OrderInfo { pub struct OrderInfo {

View file

@ -1,4 +1,4 @@
use crate::core::types::{OrderInfo, User}; use crate::types::{OrderInfo, User};
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)]
pub struct PreCheckoutQuery { pub struct PreCheckoutQuery {

View file

@ -1,4 +1,4 @@
use crate::core::types::KeyboardButton; use crate::types::KeyboardButton;
/// This object represents a custom keyboard with reply options. /// This object represents a custom keyboard with reply options.
#[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)]

View file

@ -1,4 +1,4 @@
use crate::core::types::{ use crate::types::{
ForceReply, InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply, InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove,
}; };

View file

@ -1,5 +1,5 @@
use crate::core::requests::ChatId; use crate::requests::ChatId;
use crate::core::types::{InlineKeyboardMarkup, LabeledPrice}; use crate::types::{InlineKeyboardMarkup, LabeledPrice};
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct SendInvoice { pub struct SendInvoice {

View file

@ -1,4 +1,4 @@
use crate::core::types::LabeledPrice; use crate::types::LabeledPrice;
#[derive(Debug, Hash, PartialEq, Eq, Clone, Serialize)] #[derive(Debug, Hash, PartialEq, Eq, Clone, Serialize)]
/// This object represents one shipping option. /// This object represents one shipping option.

View file

@ -1,4 +1,4 @@
use crate::core::types::{ShippingAddress, User}; use crate::types::{ShippingAddress, User};
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone)]
pub struct ShippingQuery { pub struct ShippingQuery {

Some files were not shown because too many files have changed in this diff Show more