This commit is contained in:
Temirkhan Myrzamadi 2020-01-26 04:18:13 +06:00
parent 004d5bdaf5
commit b71088746c
7 changed files with 279 additions and 25 deletions

View file

@ -146,25 +146,23 @@ pub fn polling(
stream::unfold( stream::unfold(
(allowed_updates, bot, 0), (allowed_updates, bot, 0),
move |(mut allowed_updates, bot, mut offset)| { move |(mut allowed_updates, bot, mut offset)| async move {
async move { let mut req = bot.get_updates().offset(offset);
let mut req = bot.get_updates().offset(offset); req.timeout = timeout;
req.timeout = timeout; req.limit = limit;
req.limit = limit; req.allowed_updates = allowed_updates.take();
req.allowed_updates = allowed_updates.take();
let updates = match req.send().await { let updates = match req.send().await {
Err(err) => vec![Err(err)], Err(err) => vec![Err(err)],
Ok(updates) => { Ok(updates) => {
if let Some(upd) = updates.last() { if let Some(upd) = updates.last() {
offset = upd.id + 1; offset = upd.id + 1;
}
updates.into_iter().map(Ok).collect::<Vec<_>>()
} }
}; updates.into_iter().map(Ok).collect::<Vec<_>>()
}
};
Some((stream::iter(updates), (allowed_updates, bot, offset))) Some((stream::iter(updates), (allowed_updates, bot, offset)))
}
}, },
) )
.flatten() .flatten()

View file

@ -39,13 +39,11 @@ pub async fn download_file_stream(
.await? .await?
.error_for_status()?; .error_for_status()?;
Ok(futures::stream::unfold(res, |mut res| { Ok(futures::stream::unfold(res, |mut res| async {
async { match res.chunk().await {
match res.chunk().await { Err(err) => Some((Err(err), res)),
Err(err) => Some((Err(err), res)), Ok(Some(c)) => Some((Ok(c), res)),
Ok(Some(c)) => Some((Ok(c), res)), Ok(None) => None,
Ok(None) => None,
}
} }
})) }))
} }

View file

@ -0,0 +1,118 @@
use crate::{
network,
requests::form_builder::FormBuilder,
types::{InputFile, MaskPosition, True},
Bot,
};
use crate::requests::{Request, ResponseResult};
/// Use this method to add a new sticker to a set created by the bot.
///
/// [The official docs](https://core.telegram.org/bots/api#addstickertoset).
#[derive(Copy, Eq, PartialEq, Debug, Clone)]
pub struct AddStickerToSet<'a> {
bot: &'a Bot,
user_id: i32,
name: String,
png_sticker: InputFile,
emojis: String,
mask_position: Option<MaskPosition>,
}
#[async_trait::async_trait]
impl Request for AddStickerToSet<'_> {
type Output = True;
async fn send(&self) -> ResponseResult<True> {
network::request_multipart(
self.bot.client(),
self.bot.token(),
"addStickerToSet",
FormBuilder::new()
.add("user_id", &self.user_id)
.await
.add("name", &self.name)
.await
.add("png_sticker", &self.png_sticker)
.await
.add("emojis", &self.emojis)
.await
.add("mask_position", &self.mask_position)
.await
.build(),
)
.await
}
}
impl<'a> AddStickerToSet<'a> {
pub(crate) fn new<N, E>(
bot: &'a Bot,
user_id: i32,
name: N,
png_sticker: InputFile,
emojis: E,
) -> Self
where
N: Into<String>,
E: Into<String>,
{
Self {
bot: BotWrapper(bot),
user_id,
name: name.into(),
png_sticker,
emojis: emojis.into(),
mask_position: None,
}
}
/// User identifier of sticker set owner.
pub fn user_id(mut self, val: i32) -> Self {
self.user_id = val;
self
}
/// Sticker set name.
pub fn name<T>(mut self, val: T) -> Self
where
T: Into<String>,
{
self.name = val.into();
self
}
/// **Png** image with the sticker, must be up to 512 kilobytes in size,
/// dimensions must not exceed 512px, and either width or height must be
/// exactly 512px.
///
/// Pass [`InputFile::File`] to send a file that exists on
/// the Telegram servers (recommended), pass an [`InputFile::Url`] for
/// Telegram to get a .webp file from the Internet, or upload a new one
/// using [`InputFile::FileId`]. [More info on Sending Files »].
///
/// [`InputFile::File`]: crate::types::InputFile::File
/// [`InputFile::Url`]: crate::types::InputFile::Url
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
pub fn png_sticker(mut self, val: InputFile) -> Self {
self.png_sticker = val;
self
}
/// One or more emoji corresponding to the sticker.
pub fn emojis<T>(mut self, val: T) -> Self
where
T: Into<String>,
{
self.emojis = val.into();
self
}
/// A JSON-serialized object for position where the mask should be placed on
/// faces.
pub fn mask_position(mut self, val: MaskPosition) -> Self {
self.mask_position = Some(val);
self
}
}

View file

@ -0,0 +1,118 @@
use crate::{
network,
requests::form_builder::FormBuilder,
types::{InputFile, MaskPosition, True},
Bot,
};
use crate::requests::{Request, ResponseResult};
/// Use this method to add a new sticker to a set created by the bot.
///
/// [The official docs](https://core.telegram.org/bots/api#addstickertoset).
#[derive(Copy, Eq, PartialEq, Debug, Clone)]
pub struct AddStickerToSet<'a> {
bot: &'a Bot,
user_id: i32,
name: String,
png_sticker: InputFile,
emojis: String,
mask_position: Option<MaskPosition>,
}
#[async_trait::async_trait]
impl Request for AddStickerToSet<'_> {
type Output = True;
async fn send(&self) -> ResponseResult<True> {
network::request_multipart(
self.bot.client(),
self.bot.token(),
"addStickerToSet",
FormBuilder::new()
.add("user_id", &self.user_id)
.await
.add("name", &self.name)
.await
.add("png_sticker", &self.png_sticker)
.await
.add("emojis", &self.emojis)
.await
.add("mask_position", &self.mask_position)
.await
.build(),
)
.await
}
}
impl<'a> AddStickerToSet<'a> {
pub(crate) fn new<N, E>(
bot: &'a Bot,
user_id: i32,
name: N,
png_sticker: InputFile,
emojis: E,
) -> Self
where
N: Into<String>,
E: Into<String>,
{
Self {
bot,
user_id,
name: name.into(),
png_sticker,
emojis: emojis.into(),
mask_position: None,
}
}
/// User identifier of sticker set owner.
pub fn user_id(mut self, val: i32) -> Self {
self.user_id = val;
self
}
/// Sticker set name.
pub fn name<T>(mut self, val: T) -> Self
where
T: Into<String>,
{
self.name = val.into();
self
}
/// **Png** image with the sticker, must be up to 512 kilobytes in size,
/// dimensions must not exceed 512px, and either width or height must be
/// exactly 512px.
///
/// Pass [`InputFile::File`] to send a file that exists on
/// the Telegram servers (recommended), pass an [`InputFile::Url`] for
/// Telegram to get a .webp file from the Internet, or upload a new one
/// using [`InputFile::FileId`]. [More info on Sending Files »].
///
/// [`InputFile::File`]: crate::types::InputFile::File
/// [`InputFile::Url`]: crate::types::InputFile::Url
/// [`InputFile::FileId`]: crate::types::InputFile::FileId
pub fn png_sticker(mut self, val: InputFile) -> Self {
self.png_sticker = val;
self
}
/// One or more emoji corresponding to the sticker.
pub fn emojis<T>(mut self, val: T) -> Self
where
T: Into<String>,
{
self.emojis = val.into();
self
}
/// A JSON-serialized object for position where the mask should be placed on
/// faces.
pub fn mask_position(mut self, val: MaskPosition) -> Self {
self.mask_position = Some(val);
self
}
}

View file

@ -0,0 +1,15 @@
use crate::{
network,
requests::form_builder::FormBuilder,
types::{InputFile, MaskPosition, True},
Bot,
};
use crate::requests::{Request, ResponseResult};
/// Use this method to add a new sticker to a set created by the bot.
///
/// [The official docs](https://core.telegram.org/bots/api#addstickertoset).
#[derive(Copy, Eq, PartialEq, Debug, Clone)]
pub struct AddStickerToSet<'a> {

View file

@ -812,7 +812,13 @@ impl Message {
.. ..
}, },
.. ..
} => Some(reqwest::Url::parse(format!("https://t.me/{0}/{1}/", username, self.id).as_str()).unwrap()), } => Some(
reqwest::Url::parse(
format!("https://t.me/{0}/{1}/", username, self.id)
.as_str(),
)
.unwrap(),
),
_ => None, _ => None,
} }
} }

View file

@ -41,7 +41,8 @@ impl User {
} }
pub fn url(&self) -> reqwest::Url { pub fn url(&self) -> reqwest::Url {
reqwest::Url::parse(format!("tg://user/?id={}", self.id).as_str()).unwrap() reqwest::Url::parse(format!("tg://user/?id={}", self.id).as_str())
.unwrap()
} }
} }