Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/teloxide-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Seconds` type, which represents a duration is seconds ([#859][pr859])
- `VideoChatEnded::duration` field that was previously missed ([#859][pr859])
- `ThreadId` newtype over `MessageId`, used for identifying reply threads ([#887][pr887])
- `ChatId::as_user` ([#905][pr905])
- Implement `PartialEq<ChatId> for UserId` and `PartialEq<UserId> for ChatId` ([#905][pr905])
- `ChatId::{MIN, MAX}` ([#905][pr905])

[pr851]: https://github.com/teloxide/teloxide/pull/851
[pr887]: https://github.com/teloxide/teloxide/pull/887
[pr905]: https://github.com/teloxide/teloxide/pull/905

### Fixed

Expand Down
31 changes: 29 additions & 2 deletions crates/teloxide-core/src/types/chat_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ impl ChatId {
matches!(self.to_bare(), BareChatId::Channel(_))
}

/// Returns user id, if this is an id of a user.
#[must_use]
pub fn as_user(self) -> Option<UserId> {
match self.to_bare() {
BareChatId::User(u) => Some(u),
BareChatId::Group(_) | BareChatId::Channel(_) => None,
}
}

/// Converts this id to "bare" MTProto peer id.
///
/// See [`BareChatId`] for more.
Expand All @@ -73,6 +82,12 @@ impl From<UserId> for ChatId {
}
}

impl PartialEq<UserId> for ChatId {
fn eq(&self, other: &UserId) -> bool {
self.is_user() && *self == ChatId::from(*other)
}
}

impl BareChatId {
/// Converts bare chat id back to normal bot API [`ChatId`].
#[allow(unused)]
Expand All @@ -92,8 +107,8 @@ const MIN_MARKED_CHANNEL_ID: i64 = -1997852516352;
const MAX_MARKED_CHANNEL_ID: i64 = -1000000000000;
const MIN_MARKED_CHAT_ID: i64 = MAX_MARKED_CHANNEL_ID + 1;
const MAX_MARKED_CHAT_ID: i64 = MIN_USER_ID - 1;
const MIN_USER_ID: i64 = 0;
const MAX_USER_ID: i64 = (1 << 40) - 1;
pub(crate) const MIN_USER_ID: i64 = 0;
pub(crate) const MAX_USER_ID: i64 = (1 << 40) - 1;

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -143,4 +158,16 @@ mod tests {
fn display() {
assert_eq!(ChatId(1).to_string(), "1");
}

#[test]
fn user_id_eq() {
assert_eq!(ChatId(12), UserId(12));
assert_eq!(ChatId(4652762), UserId(4652762));
assert_ne!(ChatId(17), UserId(42));

// The user id is not well formed, so even though `-1 == max` is true,
// we don't want user id to match
assert_eq!(-1i64, u64::MAX as i64);
assert_ne!(ChatId(-1), UserId(u64::MAX));
}
}
15 changes: 15 additions & 0 deletions crates/teloxide-core/src/types/user_id.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use serde::{Deserialize, Serialize};

use crate::types::{ChatId, MAX_USER_ID, MIN_USER_ID};

/// Identifier of a user.
#[derive(Clone, Copy)]
#[derive(Debug, derive_more::Display)]
Expand Down Expand Up @@ -50,6 +52,19 @@ impl UserId {

self == TELEGRAM_USER_ID
}

/// The smallest user id that could possibly be returned by Telegram.
pub const MIN: Self = Self(MIN_USER_ID as u64);

/// The largest user id that could possibly be returned by Telegram.
pub const MAX: Self = Self(MAX_USER_ID as u64);
}

impl PartialEq<ChatId> for UserId {
fn eq(&self, other: &ChatId) -> bool {
// Reuse `PartialEq<UserId> for ChatId` impl
other == self
}
}

#[cfg(test)]
Expand Down