mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-10 20:12:25 +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])
|
- `InputFile` and related structures now do **not** implement `PartialEq`, `Eq` and `Hash` ([#133][pr133])
|
||||||
- How forwarded messages are represented ([#151][pr151])
|
- How forwarded messages are represented ([#151][pr151])
|
||||||
- `RequestError::InvalidJson` now has a `raw` field with raw json for easier debugability ([#150][pr150])
|
- `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
|
[pr115]: https://github.com/teloxide/teloxide-core/pull/115
|
||||||
[pr125]: https://github.com/teloxide/teloxide-core/pull/125
|
[pr125]: https://github.com/teloxide/teloxide-core/pull/125
|
||||||
[pr134]: https://github.com/teloxide/teloxide-core/pull/134
|
[pr134]: https://github.com/teloxide/teloxide-core/pull/134
|
||||||
[pr150]: https://github.com/teloxide/teloxide-core/pull/150
|
[pr150]: https://github.com/teloxide/teloxide-core/pull/150
|
||||||
|
[pr157]: https://github.com/teloxide/teloxide-core/pull/157
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,9 @@ once_cell = "1.5.0"
|
||||||
never = "0.1.0"
|
never = "0.1.0"
|
||||||
chrono = { version = "0.4.19", default-features = false }
|
chrono = { version = "0.4.19", default-features = false }
|
||||||
either = "1.6.1"
|
either = "1.6.1"
|
||||||
|
bitflags = { version = "1.2" }
|
||||||
|
|
||||||
vecrem = { version = "0.1", optional = true }
|
vecrem = { version = "0.1", optional = true }
|
||||||
bitflags = { version = "1.2", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
|
@ -66,7 +66,7 @@ nightly = []
|
||||||
throttle = ["vecrem"]
|
throttle = ["vecrem"]
|
||||||
|
|
||||||
# Trace bot adaptor
|
# Trace bot adaptor
|
||||||
trace_adaptor = ["bitflags"]
|
trace_adaptor = []
|
||||||
|
|
||||||
# Erased bot adaptor
|
# Erased bot adaptor
|
||||||
erased = []
|
erased = []
|
||||||
|
|
|
@ -1,96 +1,192 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::ops::Not;
|
||||||
|
|
||||||
/// Describes actions that a non-administrator user is allowed to take in a
|
bitflags::bitflags! {
|
||||||
/// chat.
|
/// 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]
|
/// [The official docs](https://core.telegram.org/bots/api#chatpermissions).
|
||||||
#[derive(Copy, Clone, Default, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
///
|
||||||
pub struct ChatPermissions {
|
/// ## Examples
|
||||||
/// `true`, if the user is allowed to send text messages, contacts,
|
///
|
||||||
/// locations and venues.
|
/// ```
|
||||||
pub can_send_messages: Option<bool>,
|
/// 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,
|
/// Set if the user is allowed to send audios, documents,
|
||||||
/// photos, videos, video notes and voice notes, implies
|
/// photos, videos, video notes and voice notes, implies
|
||||||
/// `can_send_messages`.
|
/// `SEND_MESSAGES`.
|
||||||
pub can_send_media_messages: Option<bool>,
|
const SEND_MEDIA_MESSAGES = (1 << 1) | Self::SEND_MESSAGES.bits;
|
||||||
|
|
||||||
/// `true`, if the user is allowed to send polls, implies
|
/// Set if the user is allowed to send polls, implies
|
||||||
/// `can_send_messages`.
|
/// `SEND_MESSAGES`.
|
||||||
pub can_send_polls: Option<bool>,
|
const SEND_POLLS = (1 << 2) | Self::SEND_MESSAGES.bits;
|
||||||
|
|
||||||
/// `true`, if the user is allowed to send animations, games, stickers and
|
/// Set if the user is allowed to send animations, games, stickers and
|
||||||
/// use inline bots, implies `can_send_media_messages`.
|
/// use inline bots, implies `SEND_MEDIA_MESSAGES`.
|
||||||
pub can_send_other_messages: Option<bool>,
|
const SEND_OTHER_MESSAGES = (1 << 3) | Self::SEND_MEDIA_MESSAGES.bits;
|
||||||
|
|
||||||
/// `true`, if the user is allowed to add web page previews to
|
/// Set if the user is allowed to add web page previews to
|
||||||
/// their messages, implies `can_send_media_messages`.
|
/// their messages, implies `SEND_MEDIA_MESSAGES`.
|
||||||
pub can_add_web_page_previews: Option<bool>,
|
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
|
/// Set if the user is allowed to change the chat title, photo and
|
||||||
/// other settings. Ignored in public supergroups.
|
/// other settings. Ignored in public supergroups.
|
||||||
pub can_change_info: Option<bool>,
|
const CHANGE_INFO = (1 << 5);
|
||||||
|
|
||||||
/// `true`, if the user is allowed to invite new users to the chat.
|
/// Set if the user is allowed to invite new users to the chat.
|
||||||
pub can_invite_users: Option<bool>,
|
const INVITE_USERS = (1 << 6);
|
||||||
|
|
||||||
/// `true`, if the user is allowed to pin messages. Ignored in public
|
/// Set if the user is allowed to pin messages. Ignored in public
|
||||||
/// supergroups.
|
/// supergroups.
|
||||||
pub can_pin_messages: Option<bool>,
|
const PIN_MESSAGES = (1 << 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatPermissions {
|
/// Helper for (de)serialization
|
||||||
pub const fn new() -> Self {
|
#[derive(Serialize, Deserialize)]
|
||||||
Self {
|
struct ChatPermissionsRaw {
|
||||||
can_send_messages: None,
|
#[serde(default, skip_serializing_if = "Not::not")]
|
||||||
can_send_media_messages: None,
|
can_send_messages: bool,
|
||||||
can_send_polls: None,
|
|
||||||
can_send_other_messages: None,
|
#[serde(default, skip_serializing_if = "Not::not")]
|
||||||
can_add_web_page_previews: None,
|
can_send_media_messages: bool,
|
||||||
can_change_info: None,
|
|
||||||
can_invite_users: None,
|
#[serde(default, skip_serializing_if = "Not::not")]
|
||||||
can_pin_messages: None,
|
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 {
|
impl From<ChatPermissionsRaw> for ChatPermissions {
|
||||||
self.can_send_messages = Some(val);
|
fn from(
|
||||||
self
|
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 {
|
if can_send_messages {
|
||||||
self.can_send_media_messages = Some(val);
|
this |= Self::SEND_MESSAGES;
|
||||||
self
|
}
|
||||||
}
|
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 {
|
this
|
||||||
self.can_send_polls = Some(val);
|
}
|
||||||
self
|
}
|
||||||
}
|
|
||||||
|
#[cfg(test)]
|
||||||
pub const fn can_send_other_messages(mut self, val: bool) -> Self {
|
mod tests {
|
||||||
self.can_send_other_messages = Some(val);
|
use super::ChatPermissions;
|
||||||
self
|
|
||||||
}
|
#[test]
|
||||||
|
fn serialization() {
|
||||||
pub const fn can_add_web_page_previews(mut self, val: bool) -> Self {
|
let permissions = ChatPermissions::SEND_MEDIA_MESSAGES | ChatPermissions::PIN_MESSAGES;
|
||||||
self.can_add_web_page_previews = Some(val);
|
let expected =
|
||||||
self
|
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);
|
||||||
pub const fn can_change_info(mut self, val: bool) -> Self {
|
}
|
||||||
self.can_change_info = Some(val);
|
|
||||||
self
|
#[test]
|
||||||
}
|
fn deserialization() {
|
||||||
|
let json =
|
||||||
pub const fn can_invite_users(mut self, val: bool) -> Self {
|
r#"{"can_send_messages":true,"can_send_media_messages":true,"can_pin_messages":true}"#;
|
||||||
self.can_invite_users = Some(val);
|
let expected = ChatPermissions::SEND_MEDIA_MESSAGES | ChatPermissions::PIN_MESSAGES;
|
||||||
self
|
let actual = serde_json::from_str(json).unwrap();
|
||||||
}
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
pub const fn can_pin_messages(mut self, val: bool) -> Self {
|
|
||||||
self.can_pin_messages = Some(val);
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue