mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-23 06:51:01 +01:00
Make ChatPermissions into bitflags
This commit is contained in:
parent
fd3ef0bdf3
commit
62e9e8afd4
3 changed files with 178 additions and 80 deletions
|
@ -43,11 +43,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `InputFile` and related structures now do **not** implement `PartialEq`, `Eq` and `Hash` ([#133][pr133])
|
||||
- How forwarded messages are represented ([#151][pr151])
|
||||
- `RequestError::InvalidJson` now has a `raw` field with raw json for easier debugability ([#150][pr150])
|
||||
- `ChatPermissions` is now bitflags ([#157][pr157])
|
||||
|
||||
[pr115]: https://github.com/teloxide/teloxide-core/pull/115
|
||||
[pr125]: https://github.com/teloxide/teloxide-core/pull/125
|
||||
[pr134]: https://github.com/teloxide/teloxide-core/pull/134
|
||||
[pr150]: https://github.com/teloxide/teloxide-core/pull/150
|
||||
[pr157]: https://github.com/teloxide/teloxide-core/pull/157
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -42,9 +42,9 @@ once_cell = "1.5.0"
|
|||
never = "0.1.0"
|
||||
chrono = { version = "0.4.19", default-features = false }
|
||||
either = "1.6.1"
|
||||
bitflags = { version = "1.2" }
|
||||
|
||||
vecrem = { version = "0.1", optional = true }
|
||||
bitflags = { version = "1.2", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_env_logger = "0.4"
|
||||
|
@ -66,7 +66,7 @@ nightly = []
|
|||
throttle = ["vecrem"]
|
||||
|
||||
# Trace bot adaptor
|
||||
trace_adaptor = ["bitflags"]
|
||||
trace_adaptor = []
|
||||
|
||||
# Erased bot adaptor
|
||||
erased = []
|
||||
|
|
|
@ -1,96 +1,192 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Not;
|
||||
|
||||
/// Describes actions that a non-administrator user is allowed to take in a
|
||||
/// chat.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#chatpermissions).
|
||||
#[serde_with_macros::skip_serializing_none]
|
||||
#[derive(Copy, Clone, Default, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ChatPermissions {
|
||||
/// `true`, if the user is allowed to send text messages, contacts,
|
||||
/// locations and venues.
|
||||
pub can_send_messages: Option<bool>,
|
||||
bitflags::bitflags! {
|
||||
/// Describes actions that a non-administrator user is allowed to take in a
|
||||
/// chat.
|
||||
///
|
||||
/// [The official docs](https://core.telegram.org/bots/api#chatpermissions).
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// ```
|
||||
/// use teloxide_core::types::ChatPermissions;
|
||||
///
|
||||
/// // No permissions, nothing is allowed
|
||||
/// let _ = ChatPermissions::empty();
|
||||
///
|
||||
/// // All permissions, everything is allowed
|
||||
/// let _ = ChatPermissions::all();
|
||||
///
|
||||
/// // One particular permission
|
||||
/// let permissions_v0 = ChatPermissions::INVITE_USERS;
|
||||
///
|
||||
/// // Check what is permitted
|
||||
/// assert!(permissions_v0.contains(ChatPermissions::INVITE_USERS));
|
||||
/// assert!(!permissions_v0.contains(ChatPermissions::SEND_MESSAGES));
|
||||
///
|
||||
/// // Union, add permissions
|
||||
/// let permissions_v1 = permissions_v0 | ChatPermissions::SEND_MEDIA_MESSAGES;
|
||||
/// assert!(permissions_v1.contains(ChatPermissions::INVITE_USERS));
|
||||
/// assert!(permissions_v1.contains(ChatPermissions::SEND_MEDIA_MESSAGES));
|
||||
///
|
||||
/// // Implied by `SEND_MEDIA_MESSAGES`
|
||||
/// assert!(permissions_v1.contains(ChatPermissions::SEND_MESSAGES));
|
||||
///
|
||||
/// // Difference, remove permissions
|
||||
/// let permissions_v2 = permissions_v1 - ChatPermissions::SEND_MEDIA_MESSAGES;
|
||||
/// assert!(!permissions_v2.contains(ChatPermissions::SEND_MEDIA_MESSAGES));
|
||||
///
|
||||
/// // Removing `SEND_MEDIA_MESSAGES` also removes `SEND_MESSAGES` and vice versa
|
||||
/// // because `SEND_MESSAGES` is implied by `SEND_MEDIA_MESSAGES`
|
||||
/// assert!(!permissions_v2.contains(ChatPermissions::SEND_MESSAGES));
|
||||
///
|
||||
/// let permissions_v3 = permissions_v1 - ChatPermissions::SEND_MESSAGES;
|
||||
/// assert!(!permissions_v3.contains(ChatPermissions::SEND_MEDIA_MESSAGES));
|
||||
/// ```
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(from = "ChatPermissionsRaw", into = "ChatPermissionsRaw")]
|
||||
pub struct ChatPermissions: u8 {
|
||||
/// Set if the user is allowed to send text messages, contacts,
|
||||
/// locations and venues.
|
||||
const SEND_MESSAGES = 1;
|
||||
|
||||
/// `true`, if the user is allowed to send audios, documents,
|
||||
/// photos, videos, video notes and voice notes, implies
|
||||
/// `can_send_messages`.
|
||||
pub can_send_media_messages: Option<bool>,
|
||||
/// Set if the user is allowed to send audios, documents,
|
||||
/// photos, videos, video notes and voice notes, implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_MEDIA_MESSAGES = (1 << 1) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// `true`, if the user is allowed to send polls, implies
|
||||
/// `can_send_messages`.
|
||||
pub can_send_polls: Option<bool>,
|
||||
/// Set if the user is allowed to send polls, implies
|
||||
/// `SEND_MESSAGES`.
|
||||
const SEND_POLLS = (1 << 2) | Self::SEND_MESSAGES.bits;
|
||||
|
||||
/// `true`, if the user is allowed to send animations, games, stickers and
|
||||
/// use inline bots, implies `can_send_media_messages`.
|
||||
pub can_send_other_messages: Option<bool>,
|
||||
/// Set if the user is allowed to send animations, games, stickers and
|
||||
/// use inline bots, implies `SEND_MEDIA_MESSAGES`.
|
||||
const SEND_OTHER_MESSAGES = (1 << 3) | Self::SEND_MEDIA_MESSAGES.bits;
|
||||
|
||||
/// `true`, if the user is allowed to add web page previews to
|
||||
/// their messages, implies `can_send_media_messages`.
|
||||
pub can_add_web_page_previews: Option<bool>,
|
||||
/// Set if the user is allowed to add web page previews to
|
||||
/// their messages, implies `SEND_MEDIA_MESSAGES`.
|
||||
const ADD_WEB_PAGE_PREVIEWS = (1 << 4) | Self::SEND_MEDIA_MESSAGES.bits;
|
||||
|
||||
/// `true`, if the user is allowed to change the chat title, photo and
|
||||
/// other settings. Ignored in public supergroups.
|
||||
pub can_change_info: Option<bool>,
|
||||
/// Set if the user is allowed to change the chat title, photo and
|
||||
/// other settings. Ignored in public supergroups.
|
||||
const CHANGE_INFO = (1 << 5);
|
||||
|
||||
/// `true`, if the user is allowed to invite new users to the chat.
|
||||
pub can_invite_users: Option<bool>,
|
||||
/// Set if the user is allowed to invite new users to the chat.
|
||||
const INVITE_USERS = (1 << 6);
|
||||
|
||||
/// `true`, if the user is allowed to pin messages. Ignored in public
|
||||
/// supergroups.
|
||||
pub can_pin_messages: Option<bool>,
|
||||
/// Set if the user is allowed to pin messages. Ignored in public
|
||||
/// supergroups.
|
||||
const PIN_MESSAGES = (1 << 7);
|
||||
}
|
||||
}
|
||||
|
||||
impl ChatPermissions {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
can_send_messages: None,
|
||||
can_send_media_messages: None,
|
||||
can_send_polls: None,
|
||||
can_send_other_messages: None,
|
||||
can_add_web_page_previews: None,
|
||||
can_change_info: None,
|
||||
can_invite_users: None,
|
||||
can_pin_messages: None,
|
||||
/// Helper for (de)serialization
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ChatPermissionsRaw {
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_send_messages: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_send_media_messages: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_send_polls: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_send_other_messages: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_add_web_page_previews: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_change_info: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_invite_users: bool,
|
||||
|
||||
#[serde(default, skip_serializing_if = "Not::not")]
|
||||
can_pin_messages: bool,
|
||||
}
|
||||
|
||||
impl Into<ChatPermissionsRaw> for ChatPermissions {
|
||||
fn into(self) -> ChatPermissionsRaw {
|
||||
ChatPermissionsRaw {
|
||||
can_send_messages: self.contains(ChatPermissions::SEND_MESSAGES),
|
||||
can_send_media_messages: self.contains(ChatPermissions::SEND_MEDIA_MESSAGES),
|
||||
can_send_polls: self.contains(ChatPermissions::SEND_POLLS),
|
||||
can_send_other_messages: self.contains(ChatPermissions::SEND_OTHER_MESSAGES),
|
||||
can_add_web_page_previews: self.contains(ChatPermissions::ADD_WEB_PAGE_PREVIEWS),
|
||||
can_change_info: self.contains(ChatPermissions::CHANGE_INFO),
|
||||
can_invite_users: self.contains(ChatPermissions::INVITE_USERS),
|
||||
can_pin_messages: self.contains(ChatPermissions::PIN_MESSAGES),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn can_send_messages(mut self, val: bool) -> Self {
|
||||
self.can_send_messages = Some(val);
|
||||
self
|
||||
}
|
||||
impl From<ChatPermissionsRaw> for ChatPermissions {
|
||||
fn from(
|
||||
ChatPermissionsRaw {
|
||||
can_send_messages,
|
||||
can_send_media_messages,
|
||||
can_send_polls,
|
||||
can_send_other_messages,
|
||||
can_add_web_page_previews,
|
||||
can_change_info,
|
||||
can_invite_users,
|
||||
can_pin_messages,
|
||||
}: ChatPermissionsRaw,
|
||||
) -> Self {
|
||||
let mut this = Self::empty();
|
||||
|
||||
pub const fn can_send_media_messages(mut self, val: bool) -> Self {
|
||||
self.can_send_media_messages = Some(val);
|
||||
self
|
||||
}
|
||||
if can_send_messages {
|
||||
this |= Self::SEND_MESSAGES;
|
||||
}
|
||||
if can_send_media_messages {
|
||||
this |= Self::SEND_MEDIA_MESSAGES
|
||||
}
|
||||
if can_send_polls {
|
||||
this |= Self::SEND_POLLS;
|
||||
}
|
||||
if can_send_other_messages {
|
||||
this |= Self::SEND_OTHER_MESSAGES;
|
||||
}
|
||||
if can_add_web_page_previews {
|
||||
this |= Self::ADD_WEB_PAGE_PREVIEWS;
|
||||
}
|
||||
if can_change_info {
|
||||
this |= Self::CHANGE_INFO;
|
||||
}
|
||||
if can_invite_users {
|
||||
this |= Self::INVITE_USERS;
|
||||
}
|
||||
if can_pin_messages {
|
||||
this |= Self::PIN_MESSAGES;
|
||||
}
|
||||
|
||||
pub const fn can_send_polls(mut self, val: bool) -> Self {
|
||||
self.can_send_polls = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn can_send_other_messages(mut self, val: bool) -> Self {
|
||||
self.can_send_other_messages = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn can_add_web_page_previews(mut self, val: bool) -> Self {
|
||||
self.can_add_web_page_previews = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn can_change_info(mut self, val: bool) -> Self {
|
||||
self.can_change_info = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn can_invite_users(mut self, val: bool) -> Self {
|
||||
self.can_invite_users = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
pub const fn can_pin_messages(mut self, val: bool) -> Self {
|
||||
self.can_pin_messages = Some(val);
|
||||
self
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ChatPermissions;
|
||||
|
||||
#[test]
|
||||
fn serialization() {
|
||||
let permissions = ChatPermissions::SEND_MEDIA_MESSAGES | ChatPermissions::PIN_MESSAGES;
|
||||
let expected =
|
||||
r#"{"can_send_messages":true,"can_send_media_messages":true,"can_pin_messages":true}"#;
|
||||
let actual = serde_json::to_string(&permissions).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialization() {
|
||||
let json =
|
||||
r#"{"can_send_messages":true,"can_send_media_messages":true,"can_pin_messages":true}"#;
|
||||
let expected = ChatPermissions::SEND_MEDIA_MESSAGES | ChatPermissions::PIN_MESSAGES;
|
||||
let actual = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue