mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-03 09:49:07 +01:00
commit
7e1c1c3e4f
4 changed files with 109 additions and 87 deletions
|
@ -60,11 +60,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- `PollAnswer::option_ids` now use `u8` instead of `i32` ([#887][pr887])
|
- `PollAnswer::option_ids` now use `u8` instead of `i32` ([#887][pr887])
|
||||||
- Use `u32` for sizes and `Seconds` for timespans in `InlineQueryResult*` ([#887][pr887])
|
- Use `u32` for sizes and `Seconds` for timespans in `InlineQueryResult*` ([#887][pr887])
|
||||||
- `SendGame::reply_to_message_id`, `SendSticker::reply_to_message_id` and `SendInvoice::reply_to_message_id` now use `MessageId` instead of `i32` ([#887][pr887])
|
- `SendGame::reply_to_message_id`, `SendSticker::reply_to_message_id` and `SendInvoice::reply_to_message_id` now use `MessageId` instead of `i32` ([#887][pr887])
|
||||||
|
- Use `UpdateId` for `Update::id` ([#892][pr892])
|
||||||
|
|
||||||
[pr852]: https://github.com/teloxide/teloxide/pull/853
|
[pr852]: https://github.com/teloxide/teloxide/pull/853
|
||||||
[pr859]: https://github.com/teloxide/teloxide/pull/859
|
[pr859]: https://github.com/teloxide/teloxide/pull/859
|
||||||
[pr876]: https://github.com/teloxide/teloxide/pull/876
|
[pr876]: https://github.com/teloxide/teloxide/pull/876
|
||||||
[pr885]: https://github.com/teloxide/teloxide/pull/885
|
[pr885]: https://github.com/teloxide/teloxide/pull/885
|
||||||
|
[pr892]: https://github.com/teloxide/teloxide/pull/892
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,11 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::{ChatId, Seconds};
|
|
||||||
|
|
||||||
use cool_asserts::assert_matches;
|
use cool_asserts::assert_matches;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
net::request::deserialize_response,
|
net::request::deserialize_response,
|
||||||
types::{True, Update, UpdateKind},
|
types::{ChatId, Seconds, True, Update, UpdateId, UpdateKind},
|
||||||
ApiError, RequestError,
|
ApiError, RequestError,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,7 +221,7 @@ mod tests {
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
let res = deserialize_response::<Vec<Update>>(json).unwrap();
|
let res = deserialize_response::<Vec<Update>>(json).unwrap();
|
||||||
assert_matches!(res, [Update { id: 0, kind: UpdateKind::PollAnswer(_) }]);
|
assert_matches!(res, [Update { id: UpdateId(0), kind: UpdateKind::PollAnswer(_) }]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that `get_updates` can work with malformed updates.
|
/// Check that `get_updates` can work with malformed updates.
|
||||||
|
@ -264,10 +262,10 @@ mod tests {
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
res,
|
res,
|
||||||
[
|
[
|
||||||
Update { id: 0, kind: UpdateKind::PollAnswer(_) },
|
Update { id: UpdateId(0), kind: UpdateKind::PollAnswer(_) },
|
||||||
Update { id: 1, kind: UpdateKind::Error(v) } if v.is_object(),
|
Update { id: UpdateId(1), kind: UpdateKind::Error(v) } if v.is_object(),
|
||||||
Update { id: 2, kind: UpdateKind::PollAnswer(_) },
|
Update { id: UpdateId(2), kind: UpdateKind::PollAnswer(_) },
|
||||||
Update { id: 3, kind: UpdateKind::Error(v) } if v.is_object(),
|
Update { id: UpdateId(3), kind: UpdateKind::Error(v) } if v.is_object(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,101 @@ pub struct Update {
|
||||||
/// week, then identifier of the next update will be chosen randomly
|
/// week, then identifier of the next update will be chosen randomly
|
||||||
/// instead of sequentially.
|
/// instead of sequentially.
|
||||||
#[serde(rename = "update_id")]
|
#[serde(rename = "update_id")]
|
||||||
pub id: i32,
|
pub id: UpdateId,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub kind: UpdateKind,
|
pub kind: UpdateKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An identifier of a telegram update.
|
||||||
|
///
|
||||||
|
/// See [`Update::id`] for more information.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct UpdateId(pub u32);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum UpdateKind {
|
||||||
|
// NB: When adding new variants, don't forget to update
|
||||||
|
// - `AllowedUpdate`
|
||||||
|
// - `Update::user`
|
||||||
|
// - `Update::chat`
|
||||||
|
// - `DpHandlerDescription::full_set`
|
||||||
|
// - `dispatching/filter_ext.rs`
|
||||||
|
/// New incoming message of any kind — text, photo, sticker, etc.
|
||||||
|
Message(Message),
|
||||||
|
|
||||||
|
/// New version of a message that is known to the bot and was edited.
|
||||||
|
EditedMessage(Message),
|
||||||
|
|
||||||
|
/// New incoming channel post of any kind — text, photo, sticker, etc.
|
||||||
|
ChannelPost(Message),
|
||||||
|
|
||||||
|
/// New version of a channel post that is known to the bot and was edited.
|
||||||
|
EditedChannelPost(Message),
|
||||||
|
|
||||||
|
/// New incoming [inline] query.
|
||||||
|
///
|
||||||
|
/// [inline]: https://core.telegram.org/bots/api#inline-mode
|
||||||
|
InlineQuery(InlineQuery),
|
||||||
|
|
||||||
|
/// The result of an [inline] query that was chosen by a user and sent to
|
||||||
|
/// their chat partner. Please see our documentation on the [feedback
|
||||||
|
/// collecting] for details on how to enable these updates for your bot.
|
||||||
|
///
|
||||||
|
/// [inline]: https://core.telegram.org/bots/api#inline-mode
|
||||||
|
/// [feedback collecting]: https://core.telegram.org/bots/inline#collecting-feedback
|
||||||
|
ChosenInlineResult(ChosenInlineResult),
|
||||||
|
|
||||||
|
/// New incoming callback query.
|
||||||
|
CallbackQuery(CallbackQuery),
|
||||||
|
|
||||||
|
/// New incoming shipping query. Only for invoices with flexible price.
|
||||||
|
ShippingQuery(ShippingQuery),
|
||||||
|
|
||||||
|
/// New incoming pre-checkout query. Contains full information about
|
||||||
|
/// checkout.
|
||||||
|
PreCheckoutQuery(PreCheckoutQuery),
|
||||||
|
|
||||||
|
/// New poll state. Bots receive only updates about stopped polls and
|
||||||
|
/// polls, which are sent by the bot.
|
||||||
|
Poll(Poll),
|
||||||
|
|
||||||
|
/// A user changed their answer in a non-anonymous poll. Bots receive new
|
||||||
|
/// votes only in polls that were sent by the bot itself.
|
||||||
|
PollAnswer(PollAnswer),
|
||||||
|
|
||||||
|
/// The bot's chat member status was updated in a chat. For private chats,
|
||||||
|
/// this update is received only when the bot is blocked or unblocked by the
|
||||||
|
/// user.
|
||||||
|
MyChatMember(ChatMemberUpdated),
|
||||||
|
|
||||||
|
/// A chat member's status was updated in a chat. The bot must be an
|
||||||
|
/// administrator in the chat and must explicitly specify
|
||||||
|
/// [`AllowedUpdate::ChatMember`] in the list of `allowed_updates` to
|
||||||
|
/// receive these updates.
|
||||||
|
///
|
||||||
|
/// [`AllowedUpdate::ChatMember`]: crate::types::AllowedUpdate::ChatMember
|
||||||
|
ChatMember(ChatMemberUpdated),
|
||||||
|
|
||||||
|
/// A request to join the chat has been sent. The bot must have the
|
||||||
|
/// can_invite_users administrator right in the chat to receive these
|
||||||
|
/// updates.
|
||||||
|
ChatJoinRequest(ChatJoinRequest),
|
||||||
|
|
||||||
|
/// An error that happened during deserialization.
|
||||||
|
///
|
||||||
|
/// This allows `teloxide` to continue working even if telegram adds a new
|
||||||
|
/// kinds of updates.
|
||||||
|
///
|
||||||
|
/// **Note that deserialize implementation always returns an empty value**,
|
||||||
|
/// teloxide fills in the data when doing deserialization.
|
||||||
|
Error(Value),
|
||||||
|
}
|
||||||
|
|
||||||
impl Update {
|
impl Update {
|
||||||
/// Returns the user that performed the action that caused this update, if
|
/// Returns the user that performed the action that caused this update, if
|
||||||
/// known.
|
/// known.
|
||||||
|
@ -129,83 +218,16 @@ impl Update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
impl UpdateId {
|
||||||
pub enum UpdateKind {
|
/// Returns the offset for the **next** update that can be used for polling.
|
||||||
// NB: When adding new variants, don't forget to update
|
|
||||||
// - `AllowedUpdate`
|
|
||||||
// - `Update::user`
|
|
||||||
// - `Update::chat`
|
|
||||||
// - `DpHandlerDescription::full_set`
|
|
||||||
// - `dispatching/filter_ext.rs`
|
|
||||||
/// New incoming message of any kind — text, photo, sticker, etc.
|
|
||||||
Message(Message),
|
|
||||||
|
|
||||||
/// New version of a message that is known to the bot and was edited.
|
|
||||||
EditedMessage(Message),
|
|
||||||
|
|
||||||
/// New incoming channel post of any kind — text, photo, sticker, etc.
|
|
||||||
ChannelPost(Message),
|
|
||||||
|
|
||||||
/// New version of a channel post that is known to the bot and was edited.
|
|
||||||
EditedChannelPost(Message),
|
|
||||||
|
|
||||||
/// New incoming [inline] query.
|
|
||||||
///
|
///
|
||||||
/// [inline]: https://core.telegram.org/bots/api#inline-mode
|
/// I.e. `self.0 + 1`.
|
||||||
InlineQuery(InlineQuery),
|
#[must_use]
|
||||||
|
pub fn as_offset(self) -> i32 {
|
||||||
|
debug_assert!(self.0 < i32::MAX as u32);
|
||||||
|
|
||||||
/// The result of an [inline] query that was chosen by a user and sent to
|
self.0 as i32 + 1
|
||||||
/// their chat partner. Please see our documentation on the [feedback
|
}
|
||||||
/// collecting] for details on how to enable these updates for your bot.
|
|
||||||
///
|
|
||||||
/// [inline]: https://core.telegram.org/bots/api#inline-mode
|
|
||||||
/// [feedback collecting]: https://core.telegram.org/bots/inline#collecting-feedback
|
|
||||||
ChosenInlineResult(ChosenInlineResult),
|
|
||||||
|
|
||||||
/// New incoming callback query.
|
|
||||||
CallbackQuery(CallbackQuery),
|
|
||||||
|
|
||||||
/// New incoming shipping query. Only for invoices with flexible price.
|
|
||||||
ShippingQuery(ShippingQuery),
|
|
||||||
|
|
||||||
/// New incoming pre-checkout query. Contains full information about
|
|
||||||
/// checkout.
|
|
||||||
PreCheckoutQuery(PreCheckoutQuery),
|
|
||||||
|
|
||||||
/// New poll state. Bots receive only updates about stopped polls and
|
|
||||||
/// polls, which are sent by the bot.
|
|
||||||
Poll(Poll),
|
|
||||||
|
|
||||||
/// A user changed their answer in a non-anonymous poll. Bots receive new
|
|
||||||
/// votes only in polls that were sent by the bot itself.
|
|
||||||
PollAnswer(PollAnswer),
|
|
||||||
|
|
||||||
/// The bot's chat member status was updated in a chat. For private chats,
|
|
||||||
/// this update is received only when the bot is blocked or unblocked by the
|
|
||||||
/// user.
|
|
||||||
MyChatMember(ChatMemberUpdated),
|
|
||||||
|
|
||||||
/// A chat member's status was updated in a chat. The bot must be an
|
|
||||||
/// administrator in the chat and must explicitly specify
|
|
||||||
/// [`AllowedUpdate::ChatMember`] in the list of `allowed_updates` to
|
|
||||||
/// receive these updates.
|
|
||||||
///
|
|
||||||
/// [`AllowedUpdate::ChatMember`]: crate::types::AllowedUpdate::ChatMember
|
|
||||||
ChatMember(ChatMemberUpdated),
|
|
||||||
|
|
||||||
/// A request to join the chat has been sent. The bot must have the
|
|
||||||
/// can_invite_users administrator right in the chat to receive these
|
|
||||||
/// updates.
|
|
||||||
ChatJoinRequest(ChatJoinRequest),
|
|
||||||
|
|
||||||
/// An error that happened during deserialization.
|
|
||||||
///
|
|
||||||
/// This allows `teloxide` to continue working even if telegram adds a new
|
|
||||||
/// kinds of updates.
|
|
||||||
///
|
|
||||||
/// **Note that deserialize implementation always returns an empty value**,
|
|
||||||
/// teloxide fills in the data when doing deserialization.
|
|
||||||
Error(Value),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for UpdateKind {
|
impl<'de> Deserialize<'de> for UpdateKind {
|
||||||
|
@ -344,7 +366,7 @@ fn empty_error() -> UpdateKind {
|
||||||
mod test {
|
mod test {
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
Chat, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, MessageCommon,
|
Chat, ChatId, ChatKind, ChatPrivate, MediaKind, MediaText, Message, MessageCommon,
|
||||||
MessageId, MessageKind, Update, UpdateKind, User, UserId,
|
MessageId, MessageKind, Update, UpdateId, UpdateKind, User, UserId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
|
@ -379,7 +401,7 @@ mod test {
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let expected = Update {
|
let expected = Update {
|
||||||
id: 892_252_934,
|
id: UpdateId(892_252_934),
|
||||||
kind: UpdateKind::Message(Message {
|
kind: UpdateKind::Message(Message {
|
||||||
via_bot: None,
|
via_bot: None,
|
||||||
id: MessageId(6557),
|
id: MessageId(6557),
|
||||||
|
|
|
@ -354,7 +354,7 @@ impl<B: Requester> Stream for PollingStream<'_, B> {
|
||||||
}
|
}
|
||||||
Ok(updates) => {
|
Ok(updates) => {
|
||||||
if let Some(upd) = updates.last() {
|
if let Some(upd) = updates.last() {
|
||||||
*this.offset = upd.id + 1;
|
*this.offset = upd.id.as_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
match *this.drop_pending_updates {
|
match *this.drop_pending_updates {
|
||||||
|
|
Loading…
Reference in a new issue