mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
TBA 6.4 type changes
This commit is contained in:
parent
644bd6e7f4
commit
58fafd4280
9 changed files with 169 additions and 3 deletions
|
@ -30,9 +30,12 @@ pub use force_reply::*;
|
||||||
pub use forum_topic::*;
|
pub use forum_topic::*;
|
||||||
pub use forum_topic_closed::*;
|
pub use forum_topic_closed::*;
|
||||||
pub use forum_topic_created::*;
|
pub use forum_topic_created::*;
|
||||||
|
pub use forum_topic_edited::*;
|
||||||
pub use forum_topic_reopened::*;
|
pub use forum_topic_reopened::*;
|
||||||
pub use game::*;
|
pub use game::*;
|
||||||
pub use game_high_score::*;
|
pub use game_high_score::*;
|
||||||
|
pub use general_forum_topic_hidden::*;
|
||||||
|
pub use general_forum_topic_unhidden::*;
|
||||||
pub use inline_keyboard_button::*;
|
pub use inline_keyboard_button::*;
|
||||||
pub use inline_keyboard_markup::*;
|
pub use inline_keyboard_markup::*;
|
||||||
pub use inline_query::*;
|
pub use inline_query::*;
|
||||||
|
@ -113,6 +116,7 @@ pub use voice::*;
|
||||||
pub use web_app_data::*;
|
pub use web_app_data::*;
|
||||||
pub use web_app_info::*;
|
pub use web_app_info::*;
|
||||||
pub use webhook_info::*;
|
pub use webhook_info::*;
|
||||||
|
pub use write_access_allowed::*;
|
||||||
|
|
||||||
mod allowed_update;
|
mod allowed_update;
|
||||||
mod animation;
|
mod animation;
|
||||||
|
@ -142,9 +146,12 @@ mod force_reply;
|
||||||
mod forum_topic;
|
mod forum_topic;
|
||||||
mod forum_topic_closed;
|
mod forum_topic_closed;
|
||||||
mod forum_topic_created;
|
mod forum_topic_created;
|
||||||
|
mod forum_topic_edited;
|
||||||
mod forum_topic_reopened;
|
mod forum_topic_reopened;
|
||||||
mod game;
|
mod game;
|
||||||
mod game_high_score;
|
mod game_high_score;
|
||||||
|
mod general_forum_topic_hidden;
|
||||||
|
mod general_forum_topic_unhidden;
|
||||||
mod inline_keyboard_button;
|
mod inline_keyboard_button;
|
||||||
mod inline_keyboard_markup;
|
mod inline_keyboard_markup;
|
||||||
mod input_file;
|
mod input_file;
|
||||||
|
@ -200,6 +207,7 @@ mod voice;
|
||||||
mod web_app_data;
|
mod web_app_data;
|
||||||
mod web_app_info;
|
mod web_app_info;
|
||||||
mod webhook_info;
|
mod webhook_info;
|
||||||
|
mod write_access_allowed;
|
||||||
|
|
||||||
mod inline_query;
|
mod inline_query;
|
||||||
mod inline_query_result;
|
mod inline_query_result;
|
||||||
|
|
|
@ -30,6 +30,21 @@ pub struct Chat {
|
||||||
///
|
///
|
||||||
/// [`GetChat`]: crate::payloads::GetChat
|
/// [`GetChat`]: crate::payloads::GetChat
|
||||||
pub message_auto_delete_time: Option<u32>,
|
pub message_auto_delete_time: Option<u32>,
|
||||||
|
|
||||||
|
/// `true`, if non-administrators can only get the list of bots and
|
||||||
|
/// administrators in the chat. Returned only in [`GetChat`].
|
||||||
|
///
|
||||||
|
/// [`GetChat`]: crate::payloads::GetChat
|
||||||
|
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_hidden_members: bool,
|
||||||
|
|
||||||
|
/// `true`, if aggressive anti-spam checks are enabled in the supergroup.
|
||||||
|
/// The field is only available to chat administrators. Returned only in
|
||||||
|
/// [`GetChat`].
|
||||||
|
///
|
||||||
|
/// [`GetChat`]: crate::payloads::GetChat
|
||||||
|
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_aggressive_anti_spam_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[serde_with_macros::skip_serializing_none]
|
#[serde_with_macros::skip_serializing_none]
|
||||||
|
|
15
crates/teloxide-core/src/types/forum_topic_edited.rs
Normal file
15
crates/teloxide-core/src/types/forum_topic_edited.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// This object represents a service message about an edited forum topic.
|
||||||
|
///
|
||||||
|
/// [The official docs](https://core.telegram.org/bots/api#forumtopicedited).
|
||||||
|
#[serde_with_macros::skip_serializing_none]
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ForumTopicEdited {
|
||||||
|
/// New name of the topic, if it was edited
|
||||||
|
pub name: Option<String>,
|
||||||
|
|
||||||
|
/// New identifier of the custom emoji shown as the topic icon, if it was
|
||||||
|
/// edited; an empty string if the icon was removed
|
||||||
|
pub icon_custom_emoji_id: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// This object represents a service message about General forum topic hidden in
|
||||||
|
/// the chat. Currently holds no information.
|
||||||
|
///
|
||||||
|
/// [The official docs](https://core.telegram.org/bots/api#generalforumtopichidden).
|
||||||
|
#[serde_with_macros::skip_serializing_none]
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct GeneralForumTopicHidden;
|
|
@ -0,0 +1,9 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// This object represents a service message about General forum topic unhidden
|
||||||
|
/// in the chat. Currently holds no information.
|
||||||
|
///
|
||||||
|
/// [The official docs](https://core.telegram.org/bots/api#generalforumtopicunhidden).
|
||||||
|
#[serde_with_macros::skip_serializing_none]
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct GeneralForumTopicUnhidden;
|
|
@ -41,11 +41,15 @@ pub struct InputMediaPhoto {
|
||||||
/// List of special entities that appear in the caption, which can be
|
/// List of special entities that appear in the caption, which can be
|
||||||
/// specified instead of `parse_mode`.
|
/// specified instead of `parse_mode`.
|
||||||
pub caption_entities: Option<Vec<MessageEntity>>,
|
pub caption_entities: Option<Vec<MessageEntity>>,
|
||||||
|
|
||||||
|
/// Pass `true` if the photo needs to be covered with a spoiler animation.
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_spoiler: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputMediaPhoto {
|
impl InputMediaPhoto {
|
||||||
pub const fn new(media: InputFile) -> Self {
|
pub const fn new(media: InputFile) -> Self {
|
||||||
Self { media, caption: None, parse_mode: None, caption_entities: None }
|
Self { media, caption: None, parse_mode: None, caption_entities: None, has_spoiler: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn media(mut self, val: InputFile) -> Self {
|
pub fn media(mut self, val: InputFile) -> Self {
|
||||||
|
@ -73,6 +77,14 @@ impl InputMediaPhoto {
|
||||||
self.caption_entities = Some(val.into_iter().collect());
|
self.caption_entities = Some(val.into_iter().collect());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets [`has_spoiler`] to `true`.
|
||||||
|
///
|
||||||
|
/// [`has_spoiler`]: InputMediaPhoto::has_spoiler
|
||||||
|
pub fn spoiler(mut self) -> Self {
|
||||||
|
self.has_spoiler = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a video to be sent.
|
/// Represents a video to be sent.
|
||||||
|
@ -117,6 +129,10 @@ pub struct InputMediaVideo {
|
||||||
|
|
||||||
/// Pass `true`, if the uploaded video is suitable for streaming.
|
/// Pass `true`, if the uploaded video is suitable for streaming.
|
||||||
pub supports_streaming: Option<bool>,
|
pub supports_streaming: Option<bool>,
|
||||||
|
|
||||||
|
/// Pass `true` if the video needs to be covered with a spoiler animation.
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_spoiler: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputMediaVideo {
|
impl InputMediaVideo {
|
||||||
|
@ -131,6 +147,7 @@ impl InputMediaVideo {
|
||||||
height: None,
|
height: None,
|
||||||
duration: None,
|
duration: None,
|
||||||
supports_streaming: None,
|
supports_streaming: None,
|
||||||
|
has_spoiler: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +201,14 @@ impl InputMediaVideo {
|
||||||
self.supports_streaming = Some(val);
|
self.supports_streaming = Some(val);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets [`has_spoiler`] to `true`.
|
||||||
|
///
|
||||||
|
/// [`has_spoiler`]: InputMediaVideo::has_spoiler
|
||||||
|
pub fn spoiler(mut self) -> Self {
|
||||||
|
self.has_spoiler = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
|
/// Represents an animation file (GIF or H.264/MPEG-4 AVC video without
|
||||||
|
@ -226,6 +251,11 @@ pub struct InputMediaAnimation {
|
||||||
|
|
||||||
/// Animation duration.
|
/// Animation duration.
|
||||||
pub duration: Option<u16>,
|
pub duration: Option<u16>,
|
||||||
|
|
||||||
|
/// Pass `true` if the animation needs to be covered with a spoiler
|
||||||
|
/// animation.
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_spoiler: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputMediaAnimation {
|
impl InputMediaAnimation {
|
||||||
|
@ -239,6 +269,7 @@ impl InputMediaAnimation {
|
||||||
height: None,
|
height: None,
|
||||||
duration: None,
|
duration: None,
|
||||||
caption_entities: None,
|
caption_entities: None,
|
||||||
|
has_spoiler: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +318,14 @@ impl InputMediaAnimation {
|
||||||
self.duration = Some(val);
|
self.duration = Some(val);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets [`has_spoiler`] to `true`.
|
||||||
|
///
|
||||||
|
/// [`has_spoiler`]: InputMediaAnimation::has_spoiler
|
||||||
|
pub fn spoiler(mut self) -> Self {
|
||||||
|
self.has_spoiler = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an audio file to be treated as music to be sent.
|
/// Represents an audio file to be treated as music to be sent.
|
||||||
|
|
|
@ -6,11 +6,12 @@ use url::Url;
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, ForumTopicClosed,
|
Animation, Audio, BareChatId, Chat, ChatId, Contact, Dice, Document, ForumTopicClosed,
|
||||||
ForumTopicCreated, ForumTopicReopened, Game, InlineKeyboardMarkup, Invoice, Location,
|
ForumTopicCreated, ForumTopicEdited, ForumTopicReopened, Game, GeneralForumTopicHidden,
|
||||||
|
GeneralForumTopicUnhidden, InlineKeyboardMarkup, Invoice, Location,
|
||||||
MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData,
|
MessageAutoDeleteTimerChanged, MessageEntity, MessageEntityRef, MessageId, PassportData,
|
||||||
PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video,
|
PhotoSize, Poll, ProximityAlertTriggered, Sticker, SuccessfulPayment, True, User, Venue, Video,
|
||||||
VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote,
|
VideoChatEnded, VideoChatParticipantsInvited, VideoChatScheduled, VideoChatStarted, VideoNote,
|
||||||
Voice, WebAppData,
|
Voice, WebAppData, WriteAccessAllowed,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This object represents a message.
|
/// This object represents a message.
|
||||||
|
@ -58,12 +59,16 @@ pub enum MessageKind {
|
||||||
Invoice(MessageInvoice),
|
Invoice(MessageInvoice),
|
||||||
SuccessfulPayment(MessageSuccessfulPayment),
|
SuccessfulPayment(MessageSuccessfulPayment),
|
||||||
ConnectedWebsite(MessageConnectedWebsite),
|
ConnectedWebsite(MessageConnectedWebsite),
|
||||||
|
WriteAccessAllowed(WriteAccessAllowed),
|
||||||
PassportData(MessagePassportData),
|
PassportData(MessagePassportData),
|
||||||
Dice(MessageDice),
|
Dice(MessageDice),
|
||||||
ProximityAlertTriggered(MessageProximityAlertTriggered),
|
ProximityAlertTriggered(MessageProximityAlertTriggered),
|
||||||
ForumTopicCreated(ForumTopicCreated),
|
ForumTopicCreated(ForumTopicCreated),
|
||||||
|
ForumTopicEdited(ForumTopicEdited),
|
||||||
ForumTopicClosed(ForumTopicClosed),
|
ForumTopicClosed(ForumTopicClosed),
|
||||||
ForumTopicReopened(ForumTopicReopened),
|
ForumTopicReopened(ForumTopicReopened),
|
||||||
|
GeneralForumTopicHidden(GeneralForumTopicHidden),
|
||||||
|
GeneralForumTopicUnhidden(GeneralForumTopicUnhidden),
|
||||||
VideoChatScheduled(MessageVideoChatScheduled),
|
VideoChatScheduled(MessageVideoChatScheduled),
|
||||||
VideoChatStarted(MessageVideoChatStarted),
|
VideoChatStarted(MessageVideoChatStarted),
|
||||||
VideoChatEnded(MessageVideoChatEnded),
|
VideoChatEnded(MessageVideoChatEnded),
|
||||||
|
@ -339,6 +344,10 @@ pub struct MediaAnimation {
|
||||||
/// bot commands, etc. that appear in the caption.
|
/// bot commands, etc. that appear in the caption.
|
||||||
#[serde(default = "Vec::new")]
|
#[serde(default = "Vec::new")]
|
||||||
pub caption_entities: Vec<MessageEntity>,
|
pub caption_entities: Vec<MessageEntity>,
|
||||||
|
|
||||||
|
/// `true`, if the message media is covered by a spoiler animation.
|
||||||
|
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_media_spoiler: bool,
|
||||||
// Note: for backward compatibility telegram also sends `document` field, but we ignore it
|
// Note: for backward compatibility telegram also sends `document` field, but we ignore it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,6 +424,10 @@ pub struct MediaPhoto {
|
||||||
#[serde(default = "Vec::new")]
|
#[serde(default = "Vec::new")]
|
||||||
pub caption_entities: Vec<MessageEntity>,
|
pub caption_entities: Vec<MessageEntity>,
|
||||||
|
|
||||||
|
/// `true`, if the message media is covered by a spoiler animation.
|
||||||
|
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_media_spoiler: bool,
|
||||||
|
|
||||||
/// The unique identifier of a media message group this message belongs
|
/// The unique identifier of a media message group this message belongs
|
||||||
/// to.
|
/// to.
|
||||||
pub media_group_id: Option<String>,
|
pub media_group_id: Option<String>,
|
||||||
|
@ -458,6 +471,10 @@ pub struct MediaVideo {
|
||||||
#[serde(default = "Vec::new")]
|
#[serde(default = "Vec::new")]
|
||||||
pub caption_entities: Vec<MessageEntity>,
|
pub caption_entities: Vec<MessageEntity>,
|
||||||
|
|
||||||
|
/// `true`, if the message media is covered by a spoiler animation.
|
||||||
|
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub has_media_spoiler: bool,
|
||||||
|
|
||||||
/// The unique identifier of a media message group this message belongs
|
/// The unique identifier of a media message group this message belongs
|
||||||
/// to.
|
/// to.
|
||||||
pub media_group_id: Option<String>,
|
pub media_group_id: Option<String>,
|
||||||
|
@ -767,6 +784,35 @@ mod getters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the message media is covered by a spoiler
|
||||||
|
/// animation.
|
||||||
|
///
|
||||||
|
/// Getter for [`MediaPhoto::has_media_spoiler`],
|
||||||
|
/// [`MediaVideo::has_media_spoiler`] and
|
||||||
|
/// [`MediaAnimation::has_media_spoiler`].
|
||||||
|
#[must_use]
|
||||||
|
pub fn has_media_spoiler(&self) -> bool {
|
||||||
|
self.common()
|
||||||
|
.map(|m| match m.media_kind {
|
||||||
|
MediaKind::Animation(MediaAnimation { has_media_spoiler, .. })
|
||||||
|
| MediaKind::Photo(MediaPhoto { has_media_spoiler, .. })
|
||||||
|
| MediaKind::Video(MediaVideo { has_media_spoiler, .. }) => has_media_spoiler,
|
||||||
|
MediaKind::Audio(_)
|
||||||
|
| MediaKind::Contact(_)
|
||||||
|
| MediaKind::Document(_)
|
||||||
|
| MediaKind::Game(_)
|
||||||
|
| MediaKind::Venue(_)
|
||||||
|
| MediaKind::Location(_)
|
||||||
|
| MediaKind::Poll(_)
|
||||||
|
| MediaKind::Sticker(_)
|
||||||
|
| MediaKind::Text(_)
|
||||||
|
| MediaKind::VideoNote(_)
|
||||||
|
| MediaKind::Voice(_)
|
||||||
|
| MediaKind::Migration(_) => false,
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn audio(&self) -> Option<&types::Audio> {
|
pub fn audio(&self) -> Option<&types::Audio> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::types::KeyboardButton;
|
||||||
/// [Introduction to bots]: https://core.telegram.org/bots#keyboards
|
/// [Introduction to bots]: https://core.telegram.org/bots#keyboards
|
||||||
#[serde_with_macros::skip_serializing_none]
|
#[serde_with_macros::skip_serializing_none]
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
|
||||||
|
// FIXME: unoption bools?
|
||||||
pub struct KeyboardMarkup {
|
pub struct KeyboardMarkup {
|
||||||
/// Array of button rows, each represented by an Array of
|
/// Array of button rows, each represented by an Array of
|
||||||
/// [`KeyboardButton`] objects
|
/// [`KeyboardButton`] objects
|
||||||
|
@ -18,6 +19,12 @@ pub struct KeyboardMarkup {
|
||||||
/// [`KeyboardButton`]: crate::types::KeyboardButton
|
/// [`KeyboardButton`]: crate::types::KeyboardButton
|
||||||
pub keyboard: Vec<Vec<KeyboardButton>>,
|
pub keyboard: Vec<Vec<KeyboardButton>>,
|
||||||
|
|
||||||
|
/// Requests clients to always show the keyboard when the regular keyboard
|
||||||
|
/// is hidden. Defaults to `false`, in which case the custom keyboard
|
||||||
|
/// can be hidden and opened with a keyboard icon.
|
||||||
|
#[serde(skip_serializing_if = "std::ops::Not::not")]
|
||||||
|
pub is_persistent: bool,
|
||||||
|
|
||||||
/// Requests clients to resize the keyboard vertically for optimal fit
|
/// Requests clients to resize the keyboard vertically for optimal fit
|
||||||
/// (e.g., make the keyboard smaller if there are just two rows of
|
/// (e.g., make the keyboard smaller if there are just two rows of
|
||||||
/// buttons). Defaults to `false`, in which case the custom keyboard is
|
/// buttons). Defaults to `false`, in which case the custom keyboard is
|
||||||
|
@ -56,6 +63,7 @@ impl KeyboardMarkup {
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
keyboard: keyboard.into_iter().map(<_>::into_iter).map(<_>::collect).collect(),
|
keyboard: keyboard.into_iter().map(<_>::into_iter).map(<_>::collect).collect(),
|
||||||
|
is_persistent: false,
|
||||||
resize_keyboard: None,
|
resize_keyboard: None,
|
||||||
one_time_keyboard: None,
|
one_time_keyboard: None,
|
||||||
input_field_placeholder: None,
|
input_field_placeholder: None,
|
||||||
|
@ -80,6 +88,14 @@ impl KeyboardMarkup {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets [`is_persistent`] to `true`.
|
||||||
|
///
|
||||||
|
/// [`is_persistent`]: KeyboardMarkup::is_persistent
|
||||||
|
pub fn persistent(mut self) -> Self {
|
||||||
|
self.is_persistent = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize_keyboard<T>(mut self, val: T) -> Self
|
pub fn resize_keyboard<T>(mut self, val: T) -> Self
|
||||||
where
|
where
|
||||||
T: Into<Option<bool>>,
|
T: Into<Option<bool>>,
|
||||||
|
|
9
crates/teloxide-core/src/types/write_access_allowed.rs
Normal file
9
crates/teloxide-core/src/types/write_access_allowed.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// This object represents a service message about a user allowing a bot added
|
||||||
|
/// to the attachment menu to write messages. Currently holds no information.
|
||||||
|
///
|
||||||
|
/// [The official docs](https://core.telegram.org/bots/api#writeaccessallowed).
|
||||||
|
#[serde_with_macros::skip_serializing_none]
|
||||||
|
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct WriteAccessAllowed;
|
Loading…
Reference in a new issue