mirror of
https://github.com/teloxide/teloxide.git
synced 2025-03-19 21:49:00 +01:00
Merge branch 'dev' into unbox_send_future
This commit is contained in:
commit
816d2bad2f
22 changed files with 206 additions and 76 deletions
|
@ -1,10 +1,10 @@
|
||||||
mod api;
|
|
||||||
mod download;
|
|
||||||
|
|
||||||
use reqwest::r#async::Client;
|
use reqwest::r#async::Client;
|
||||||
|
|
||||||
use crate::requests::RequestContext;
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
mod api;
|
||||||
|
mod download;
|
||||||
|
|
||||||
pub struct Bot {
|
pub struct Bot {
|
||||||
token: String,
|
token: String,
|
||||||
client: Client,
|
client: Client,
|
||||||
|
|
|
@ -5,11 +5,11 @@ extern crate derive_more;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|
||||||
mod network;
|
pub use errors::{DownloadError, RequestError};
|
||||||
|
|
||||||
mod errors;
|
mod errors;
|
||||||
|
mod network;
|
||||||
|
|
||||||
pub mod bot;
|
pub mod bot;
|
||||||
pub mod requests;
|
pub mod requests;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use errors::{DownloadError, RequestError};
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ use tokio::{
|
||||||
stream::Stream,
|
stream::Stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::DownloadError;
|
||||||
network::{file_url, TELEGRAM_API_URL},
|
|
||||||
DownloadError,
|
use super::TELEGRAM_API_URL;
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn download_file<D>(
|
pub async fn download_file<D>(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
|
@ -35,7 +34,10 @@ pub async fn download_file_stream(
|
||||||
token: &str,
|
token: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error> {
|
) -> Result<impl Stream<Item = Result<Chunk, reqwest::Error>>, reqwest::Error> {
|
||||||
let url = file_url(TELEGRAM_API_URL, token, path);
|
Ok(client
|
||||||
let resp = client.get(&url).send().await?.error_for_status()?;
|
.get(&super::file_url(TELEGRAM_API_URL, token, path))
|
||||||
Ok(resp.into_body())
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.into_body())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
mod download;
|
|
||||||
mod request;
|
|
||||||
mod telegram_response;
|
|
||||||
|
|
||||||
pub use download::{download_file, download_file_stream};
|
pub use download::{download_file, download_file_stream};
|
||||||
pub use request::{request_json, request_multipart};
|
pub use request::{request_json, request_multipart};
|
||||||
pub use telegram_response::TelegramResponse;
|
pub use telegram_response::TelegramResponse;
|
||||||
|
|
||||||
pub const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
mod download;
|
||||||
|
mod request;
|
||||||
|
mod telegram_response;
|
||||||
|
|
||||||
|
const TELEGRAM_API_URL: &str = "https://api.telegram.org";
|
||||||
|
|
||||||
/// Creates URL for making HTTPS requests. See the [Telegram documentation].
|
/// Creates URL for making HTTPS requests. See the [Telegram documentation].
|
||||||
///
|
///
|
||||||
|
|
|
@ -2,11 +2,9 @@ use apply::Apply;
|
||||||
use reqwest::r#async::{multipart::Form, Client, Response};
|
use reqwest::r#async::{multipart::Form, Client, Response};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{requests::ResponseResult, RequestError};
|
||||||
network::{method_url, TelegramResponse, TELEGRAM_API_URL},
|
|
||||||
requests::ResponseResult,
|
use super::{TelegramResponse, TELEGRAM_API_URL};
|
||||||
RequestError,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn request_multipart<T>(
|
pub async fn request_multipart<T>(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
|
@ -19,7 +17,7 @@ where
|
||||||
{
|
{
|
||||||
process_response(
|
process_response(
|
||||||
client
|
client
|
||||||
.post(&method_url(TELEGRAM_API_URL, token, method_name))
|
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
|
||||||
.apply(|request_builder| match params {
|
.apply(|request_builder| match params {
|
||||||
Some(params) => request_builder.multipart(params),
|
Some(params) => request_builder.multipart(params),
|
||||||
None => request_builder,
|
None => request_builder,
|
||||||
|
@ -39,7 +37,7 @@ pub async fn request_json<T: DeserializeOwned, P: Serialize>(
|
||||||
) -> ResponseResult<T> {
|
) -> ResponseResult<T> {
|
||||||
process_response(
|
process_response(
|
||||||
client
|
client
|
||||||
.post(&method_url(TELEGRAM_API_URL, token, method_name))
|
.post(&super::method_url(TELEGRAM_API_URL, token, method_name))
|
||||||
.json(params)
|
.json(params)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -51,10 +49,9 @@ pub async fn request_json<T: DeserializeOwned, P: Serialize>(
|
||||||
async fn process_response<T: DeserializeOwned>(
|
async fn process_response<T: DeserializeOwned>(
|
||||||
mut response: Response,
|
mut response: Response,
|
||||||
) -> ResponseResult<T> {
|
) -> ResponseResult<T> {
|
||||||
let response = serde_json::from_str::<TelegramResponse<T>>(
|
serde_json::from_str::<TelegramResponse<T>>(
|
||||||
&response.text().await.map_err(RequestError::NetworkError)?,
|
&response.text().await.map_err(RequestError::NetworkError)?,
|
||||||
)
|
)
|
||||||
.map_err(RequestError::InvalidJson)?;
|
.map_err(RequestError::InvalidJson)?
|
||||||
|
.into()
|
||||||
response.into()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,11 +72,10 @@ impl<'a> GetUserProfilePhotos<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn limit<T>(mut self, limit: T) -> Self
|
pub fn limit<T>(mut self, limit: T) -> Self
|
||||||
where
|
where
|
||||||
T: Into<i64>,
|
T: Into<i64>,
|
||||||
{
|
{
|
||||||
self.limit = Some(limit.into());
|
self.limit = Some(limit.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
mod form_builder;
|
use std::{future::Future, pin::Pin};
|
||||||
mod utils;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::r#async::Client;
|
use reqwest::r#async::Client;
|
||||||
|
@ -15,15 +14,21 @@ pub use self::{
|
||||||
get_me::GetMe, get_updates::GetUpdates,
|
get_me::GetMe, get_updates::GetUpdates,
|
||||||
get_user_profile_photos::GetUserProfilePhotos,
|
get_user_profile_photos::GetUserProfilePhotos,
|
||||||
kick_chat_member::KickChatMember, pin_chat_message::PinChatMessage,
|
kick_chat_member::KickChatMember, pin_chat_message::PinChatMessage,
|
||||||
restrict_chat_member::RestrictChatMember,
|
promote_chat_member::PromoteChatMember,
|
||||||
|
restrict_chat_member::RestrictChatMember, send_animation::SendAnimation,
|
||||||
send_audio::SendAudio, send_chat_action::SendChatAction,
|
send_audio::SendAudio, send_chat_action::SendChatAction,
|
||||||
send_contact::SendContact, send_location::SendLocation,
|
send_contact::SendContact, send_document::SendDocument,
|
||||||
send_media_group::SendMediaGroup, send_message::SendMessage,
|
send_location::SendLocation, send_media_group::SendMediaGroup,
|
||||||
send_photo::SendPhoto, send_poll::SendPoll, send_venue::SendVenue,
|
send_message::SendMessage, send_photo::SendPhoto, send_poll::SendPoll,
|
||||||
|
send_venue::SendVenue, send_video::SendVideo,
|
||||||
|
send_video_note::SendVideoNote, send_voice::SendVoice,
|
||||||
stop_message_live_location::StopMessageLiveLocation,
|
stop_message_live_location::StopMessageLiveLocation,
|
||||||
unban_chat_member::UnbanChatMember,
|
unban_chat_member::UnbanChatMember,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod form_builder;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
pub type ResponseResult<T> = Result<T, RequestError>;
|
pub type ResponseResult<T> = Result<T, RequestError>;
|
||||||
|
|
||||||
/// Request that can be sent to telegram.
|
/// Request that can be sent to telegram.
|
||||||
|
@ -90,15 +95,21 @@ mod get_updates;
|
||||||
mod get_user_profile_photos;
|
mod get_user_profile_photos;
|
||||||
mod kick_chat_member;
|
mod kick_chat_member;
|
||||||
mod pin_chat_message;
|
mod pin_chat_message;
|
||||||
|
mod promote_chat_member;
|
||||||
mod restrict_chat_member;
|
mod restrict_chat_member;
|
||||||
|
mod send_animation;
|
||||||
mod send_audio;
|
mod send_audio;
|
||||||
mod send_chat_action;
|
mod send_chat_action;
|
||||||
mod send_contact;
|
mod send_contact;
|
||||||
|
mod send_document;
|
||||||
mod send_location;
|
mod send_location;
|
||||||
mod send_media_group;
|
mod send_media_group;
|
||||||
mod send_message;
|
mod send_message;
|
||||||
mod send_photo;
|
mod send_photo;
|
||||||
mod send_poll;
|
mod send_poll;
|
||||||
mod send_venue;
|
mod send_venue;
|
||||||
|
mod send_video;
|
||||||
|
mod send_video_note;
|
||||||
|
mod send_voice;
|
||||||
mod stop_message_live_location;
|
mod stop_message_live_location;
|
||||||
mod unban_chat_member;
|
mod unban_chat_member;
|
||||||
|
|
|
@ -6,30 +6,38 @@ use crate::{
|
||||||
types::True
|
types::True
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 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 PinChatMessage<'a> {
|
pub struct PinChatMessage<'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)
|
||||||
pub chat_id: ChatId,
|
pub chat_id: ChatId,
|
||||||
pub message_id: i32,
|
pub message_id: i32,
|
||||||
pub disable_notification: Option<bool>
|
pub disable_notification: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PinChatMessage<'a> {
|
impl<'a> PinChatMessage<'a> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
ctx: RequestContext<'a>, chat_id: ChatId, message_id: i32
|
ctx: RequestContext<'a>,
|
||||||
|
chat_id: ChatId,
|
||||||
|
message_id: i32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { ctx, chat_id, message_id, disable_notification: None }
|
Self {
|
||||||
|
ctx,
|
||||||
|
chat_id,
|
||||||
|
message_id,
|
||||||
|
disable_notification: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_notification<T>(mut self, val: T) -> Self
|
pub fn disable_notification<T>(mut self, val: T) -> Self
|
||||||
where T: Into<bool>
|
where
|
||||||
|
T: Into<bool>,
|
||||||
{
|
{
|
||||||
self.disable_notification = Some(val.into());
|
self.disable_notification = Some(val.into());
|
||||||
self
|
self
|
||||||
|
@ -39,7 +47,6 @@ impl<'a> PinChatMessage<'a> {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<'a> Request for PinChatMessage<'a> {
|
impl<'a> Request for PinChatMessage<'a> {
|
||||||
type ReturnValue = True;
|
type ReturnValue = True;
|
||||||
|
|
||||||
async fn send_boxed(self) -> ResponseResult<Self::ReturnValue> {
|
async fn send_boxed(self) -> ResponseResult<Self::ReturnValue> {
|
||||||
self.send().await
|
self.send().await
|
||||||
}
|
}
|
||||||
|
|
8
src/requests/promote_chat_member.rs
Normal file
8
src/requests/promote_chat_member.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct PromoteChatMember<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
8
src/requests/send_animation.rs
Normal file
8
src/requests/send_animation.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SendAnimation<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
8
src/requests/send_document.rs
Normal file
8
src/requests/send_document.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SendDocument<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network,
|
network,
|
||||||
|
@ -6,8 +7,6 @@ use crate::{
|
||||||
types::{Message, ReplyMarkup},
|
types::{Message, ReplyMarkup},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
/// Use this method to send point on the map. On success, the sent [`Message`]
|
/// Use this method to send point on the map. On success, the sent [`Message`]
|
||||||
/// is returned.
|
/// is returned.
|
||||||
|
|
8
src/requests/send_video.rs
Normal file
8
src/requests/send_video.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SendVideo<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
8
src/requests/send_video_note.rs
Normal file
8
src/requests/send_video_note.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SendVideoNote<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
8
src/requests/send_voice.rs
Normal file
8
src/requests/send_voice.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::requests::RequestContext;
|
||||||
|
|
||||||
|
///TODO: add implementation
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct SendVoice<'a> {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
}
|
|
@ -1,8 +1,65 @@
|
||||||
use crate::requests::RequestContext;
|
use crate::network;
|
||||||
//TODO:: need implementation
|
use crate::requests::{
|
||||||
|
ChatId, Request, RequestContext, RequestFuture, ResponseResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Use this method to unban a previously kicked user in a supergroup or
|
||||||
|
/// channel. The user will not return to the group or channel automatically, but
|
||||||
|
/// will be able to join via link, etc. The bot must be an administrator for
|
||||||
|
/// this to work. Returns True on success.
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct UnbanChatMember<'a> {
|
pub struct UnbanChatMember<'a> {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
ctx: RequestContext<'a>,
|
ctx: RequestContext<'a>,
|
||||||
|
///Unique identifier for the target group or username of the target
|
||||||
|
/// supergroup or channel (in the format @channelusername)
|
||||||
|
pub chat_id: ChatId,
|
||||||
|
/// Unique identifier of the target user
|
||||||
|
pub user_id: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Request<'a> for UnbanChatMember<'a> {
|
||||||
|
type ReturnValue = bool;
|
||||||
|
|
||||||
|
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
network::request_json(
|
||||||
|
&self.ctx.client,
|
||||||
|
&self.ctx.token,
|
||||||
|
"unbanChatMember",
|
||||||
|
&self,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> UnbanChatMember<'a> {
|
||||||
|
pub(crate) fn new(
|
||||||
|
ctx: RequestContext<'a>,
|
||||||
|
chat_id: ChatId,
|
||||||
|
user_id: i32,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
ctx,
|
||||||
|
chat_id,
|
||||||
|
user_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chat_id<T>(mut self, chat_id: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<ChatId>,
|
||||||
|
{
|
||||||
|
self.chat_id = chat_id.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_id<T>(mut self, user_id: T) -> Self
|
||||||
|
where
|
||||||
|
T: Into<i32>,
|
||||||
|
{
|
||||||
|
self.user_id = user_id.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,9 +80,10 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::*;
|
|
||||||
use serde_json::from_str;
|
use serde_json::from_str;
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn channel_de() {
|
fn channel_de() {
|
||||||
let expected = Chat {
|
let expected = Chat {
|
||||||
|
@ -113,9 +114,9 @@ mod tests {
|
||||||
type_: (),
|
type_: (),
|
||||||
username: Some("username".into()),
|
username: Some("username".into()),
|
||||||
first_name: Some("Anon".into()),
|
first_name: Some("Anon".into()),
|
||||||
last_name: None
|
last_name: None,
|
||||||
},
|
},
|
||||||
photo: None
|
photo: None,
|
||||||
},
|
},
|
||||||
from_str(
|
from_str(
|
||||||
r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#
|
r#"{"id":0,"type":"private","username":"username","first_name":"Anon"}"#
|
||||||
|
|
|
@ -4,64 +4,68 @@ use super::passport_file::PassportFile;
|
||||||
pub struct EncryptedPassportElement {
|
pub struct EncryptedPassportElement {
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub kind: EncryptedPassportElementKind
|
pub kind: EncryptedPassportElementKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum EncryptedPassportElementKind {
|
pub enum EncryptedPassportElementKind {
|
||||||
PersonalDetails {
|
PersonalDetails {
|
||||||
data: String
|
data: String,
|
||||||
},
|
},
|
||||||
Passport {
|
Passport {
|
||||||
data: String,
|
data: String,
|
||||||
front_side: PassportFile,
|
front_side: PassportFile,
|
||||||
selfie: PassportFile,
|
selfie: PassportFile,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
DriverLicense {
|
DriverLicense {
|
||||||
data: String,
|
data: String,
|
||||||
front_side: PassportFile,
|
front_side: PassportFile,
|
||||||
reverse_side: PassportFile,
|
reverse_side: PassportFile,
|
||||||
selfie: PassportFile,
|
selfie: PassportFile,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
IdentityCard {
|
IdentityCard {
|
||||||
data: String,
|
data: String,
|
||||||
front_side: PassportFile,
|
front_side: PassportFile,
|
||||||
reverse_side: PassportFile,
|
reverse_side: PassportFile,
|
||||||
selfie: PassportFile,
|
selfie: PassportFile,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
InternalPassport {
|
InternalPassport {
|
||||||
data: String,
|
data: String,
|
||||||
front_side: PassportFile,
|
front_side: PassportFile,
|
||||||
selfie: PassportFile,
|
selfie: PassportFile,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
Address {
|
Address {
|
||||||
data: String
|
data: String,
|
||||||
},
|
},
|
||||||
UtilityBill {
|
UtilityBill {
|
||||||
files: Vec<PassportFile>,
|
files: Vec<PassportFile>,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
BankStatement {
|
BankStatement {
|
||||||
files: Vec<PassportFile>,
|
files: Vec<PassportFile>,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
RentalAgreement {
|
RentalAgreement {
|
||||||
files: Vec<PassportFile>,
|
files: Vec<PassportFile>,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
PassportRegistration {
|
PassportRegistration {
|
||||||
files: Vec<PassportFile>,
|
files: Vec<PassportFile>,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
},
|
},
|
||||||
TemporaryRegistration {
|
TemporaryRegistration {
|
||||||
files: Vec<PassportFile>,
|
files: Vec<PassportFile>,
|
||||||
translation: Option<Vec<PassportFile>>
|
translation: Option<Vec<PassportFile>>,
|
||||||
|
},
|
||||||
|
PhoneNumber {
|
||||||
|
phone_number: String,
|
||||||
|
},
|
||||||
|
Email {
|
||||||
|
email: String,
|
||||||
},
|
},
|
||||||
PhoneNumber { phone_number: String },
|
|
||||||
Email { email: String }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,9 +203,10 @@ pub enum MediaKind {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::*;
|
|
||||||
use serde_json::from_str;
|
use serde_json::from_str;
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn de_media_forwarded() {
|
fn de_media_forwarded() {
|
||||||
let json = r#"{
|
let json = r#"{
|
||||||
|
|
|
@ -12,7 +12,9 @@ pub use self::{
|
||||||
contact::Contact,
|
contact::Contact,
|
||||||
document::Document,
|
document::Document,
|
||||||
encrypted_credintials::EncryptedCredentials,
|
encrypted_credintials::EncryptedCredentials,
|
||||||
encrypted_passport_element::{EncryptedPassportElement, EncryptedPassportElementKind},
|
encrypted_passport_element::{
|
||||||
|
EncryptedPassportElement, EncryptedPassportElementKind,
|
||||||
|
},
|
||||||
file::File,
|
file::File,
|
||||||
force_reply::ForceReply,
|
force_reply::ForceReply,
|
||||||
game::Game,
|
game::Game,
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl std::convert::TryFrom<bool> for True {
|
||||||
fn try_from(value: bool) -> Result<Self, Self::Error> {
|
fn try_from(value: bool) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
true => Ok(True),
|
true => Ok(True),
|
||||||
false => Err(())
|
false => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ impl std::convert::TryFrom<bool> for True {
|
||||||
impl<'de> Deserialize<'de> for True {
|
impl<'de> Deserialize<'de> for True {
|
||||||
fn deserialize<D>(des: D) -> Result<Self, D::Error>
|
fn deserialize<D>(des: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
des.deserialize_bool(TrueVisitor)
|
des.deserialize_bool(TrueVisitor)
|
||||||
}
|
}
|
||||||
|
@ -41,11 +41,11 @@ impl<'de> Visitor<'de> for TrueVisitor {
|
||||||
|
|
||||||
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
|
fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: de::Error
|
E: de::Error,
|
||||||
{
|
{
|
||||||
match value {
|
match value {
|
||||||
true => Ok(True),
|
true => Ok(True),
|
||||||
false => Err(E::custom("expected `true`, found `false`"))
|
false => Err(E::custom("expected `true`, found `false`")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,10 @@ impl Serialize for True {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::True;
|
|
||||||
use serde_json::{from_str, to_string};
|
use serde_json::{from_str, to_string};
|
||||||
|
|
||||||
|
use super::True;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unit_true_de() {
|
fn unit_true_de() {
|
||||||
let json = "true";
|
let json = "true";
|
||||||
|
|
|
@ -16,7 +16,8 @@ pub enum UpdateKind {
|
||||||
EditedMessage(Message),
|
EditedMessage(Message),
|
||||||
ChannelPost(Message),
|
ChannelPost(Message),
|
||||||
EditedChannelPost(Message),
|
EditedChannelPost(Message),
|
||||||
InlineQuery(()), // TODO
|
InlineQuery(()),
|
||||||
|
// TODO
|
||||||
ChosenInlineResult(ChosenInlineResult),
|
ChosenInlineResult(ChosenInlineResult),
|
||||||
CallbackQuery(CallbackQuery),
|
CallbackQuery(CallbackQuery),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue