mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Fix Sticker and StickerSet with StickerFormatFlags type
This commit is contained in:
parent
c24fdf173e
commit
af4af72c2a
2 changed files with 102 additions and 71 deletions
|
@ -36,12 +36,15 @@ pub struct Sticker {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub kind: StickerKind,
|
pub kind: StickerKind,
|
||||||
|
|
||||||
/// Format of this sticker - raster/`.webp`, animated/`.tgs` or
|
/// Format flags of this sticker:
|
||||||
/// video/`.webm`.
|
///
|
||||||
|
/// `(is_animated, is_video)` == `(false, false)` - raster/`.webp` or
|
||||||
|
/// `is_animated == true` - animated/`.tgs` or
|
||||||
|
/// `is_video == true` - video/`.webm`.
|
||||||
///
|
///
|
||||||
/// In other words this represents how the sticker is encoded.
|
/// In other words this represents how the sticker is encoded.
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub format: StickerFormat,
|
pub flags: StickerFormatFlags,
|
||||||
|
|
||||||
/// Sticker thumbnail in the `.webp` or `.jpg` format.
|
/// Sticker thumbnail in the `.webp` or `.jpg` format.
|
||||||
pub thumbnail: Option<PhotoSize>,
|
pub thumbnail: Option<PhotoSize>,
|
||||||
|
@ -98,9 +101,17 @@ pub enum StickerType {
|
||||||
CustomEmoji,
|
CustomEmoji,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct StickerFormatFlags {
|
||||||
|
/// True, if the sticker is animated
|
||||||
|
pub is_animated: bool,
|
||||||
|
/// True, if the sticker is a video sticker
|
||||||
|
pub is_video: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Format of a [`Sticker`] - regular/webp, animated/tgs or video/webm.
|
/// Format of a [`Sticker`] - regular/webp, animated/tgs or video/webm.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(try_from = "StickerFormatRaw", into = "StickerFormatRaw")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum StickerFormat {
|
pub enum StickerFormat {
|
||||||
/// Image in `.png` or `.webp` format.
|
/// Image in `.png` or `.webp` format.
|
||||||
Static,
|
Static,
|
||||||
|
@ -136,36 +147,45 @@ impl Deref for Sticker {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sticker {
|
impl Sticker {
|
||||||
|
/// Returns the format of the [`Sticker`] based on the [`self.flags`] values
|
||||||
|
///
|
||||||
|
/// [`Sticker`]: Sticker
|
||||||
|
/// [`self.flags`]: Sticker::flags
|
||||||
|
#[must_use]
|
||||||
|
pub fn format(&self) -> StickerFormat {
|
||||||
|
self.flags.format()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is a "normal" raster sticker.
|
/// Returns `true` is this is a "normal" raster sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_raster()`].
|
/// Alias to [`self.format().is_raster()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_static()`]: StickerFormat::is_static
|
/// [`self.format().is_static()`]: StickerFormat::is_static
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_static(&self) -> bool {
|
pub fn is_static(&self) -> bool {
|
||||||
self.format.is_static()
|
self.format().is_static()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is an [animated] sticker.
|
/// Returns `true` is this is an [animated] sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_animated()`].
|
/// Alias to [`self.format().is_animated()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_animated()`]: StickerFormat::is_animated
|
/// [`self.format().is_animated()`]: StickerFormat::is_animated
|
||||||
/// [animated]: https://telegram.org/blog/animated-stickers
|
/// [animated]: https://telegram.org/blog/animated-stickers
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_animated(&self) -> bool {
|
pub fn is_animated(&self) -> bool {
|
||||||
self.format.is_animated()
|
self.format().is_animated()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is a [video] sticker.
|
/// Returns `true` is this is a [video] sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_video()`].
|
/// Alias to [`self.format().is_video()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_video()`]: StickerFormat::is_video
|
/// [`self.format().is_video()`]: StickerFormat::is_video
|
||||||
/// [video]: https://telegram.org/blog/video-stickers-better-reactions
|
/// [video]: https://telegram.org/blog/video-stickers-better-reactions
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_video(&self) -> bool {
|
pub fn is_video(&self) -> bool {
|
||||||
self.format.is_video()
|
self.format().is_video()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +281,17 @@ impl StickerType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StickerFormatFlags {
|
||||||
|
pub fn format(&self) -> StickerFormat {
|
||||||
|
match (self.is_animated, self.is_video) {
|
||||||
|
(false, false) => StickerFormat::Static,
|
||||||
|
(true, false) => StickerFormat::Animated,
|
||||||
|
(false, true) => StickerFormat::Video,
|
||||||
|
(true, true) => panic!("`is_animated` and `is_video` flags present at the same time"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StickerFormat {
|
impl StickerFormat {
|
||||||
/// Returns `true` if the sticker format is [`Static`].
|
/// Returns `true` if the sticker format is [`Static`].
|
||||||
///
|
///
|
||||||
|
@ -287,42 +318,31 @@ impl StickerFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct StickerFormatRaw {
|
|
||||||
is_animated: bool,
|
|
||||||
is_video: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<StickerFormatRaw> for StickerFormat {
|
|
||||||
type Error = &'static str;
|
|
||||||
|
|
||||||
fn try_from(
|
|
||||||
StickerFormatRaw { is_animated, is_video }: StickerFormatRaw,
|
|
||||||
) -> Result<Self, Self::Error> {
|
|
||||||
let ret = match (is_animated, is_video) {
|
|
||||||
(false, false) => Self::Static,
|
|
||||||
(true, false) => Self::Animated,
|
|
||||||
(false, true) => Self::Video,
|
|
||||||
(true, true) => return Err("`is_animated` and `is_video` present at the same time"),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StickerFormat> for StickerFormatRaw {
|
|
||||||
fn from(kind: StickerFormat) -> Self {
|
|
||||||
match kind {
|
|
||||||
StickerFormat::Static => Self { is_animated: false, is_video: false },
|
|
||||||
StickerFormat::Animated => Self { is_animated: true, is_video: false },
|
|
||||||
StickerFormat::Video => Self { is_animated: false, is_video: true },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::{MaskPoint, Sticker, StickerFormat, StickerType};
|
use crate::types::{MaskPoint, Sticker, StickerFormat, StickerFormatFlags, StickerType};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sticker_format_serde() {
|
||||||
|
// Ser
|
||||||
|
assert_eq!(serde_json::to_string(&StickerFormat::Static).unwrap(), r#""static""#);
|
||||||
|
assert_eq!(serde_json::to_string(&StickerFormat::Animated).unwrap(), r#""animated""#);
|
||||||
|
assert_eq!(serde_json::to_string(&StickerFormat::Video).unwrap(), r#""video""#);
|
||||||
|
|
||||||
|
// De
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<StickerFormat>(r#""static""#).unwrap(),
|
||||||
|
StickerFormat::Static
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<StickerFormat>(r#""animated""#).unwrap(),
|
||||||
|
StickerFormat::Animated
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<StickerFormat>(r#""video""#).unwrap(),
|
||||||
|
StickerFormat::Video
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mask_serde() {
|
fn mask_serde() {
|
||||||
|
@ -412,35 +432,40 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sticker_format_serde() {
|
fn sticker_format_flags_serde() {
|
||||||
{
|
{
|
||||||
let json = r#"{"is_animated":false,"is_video":false}"#;
|
let json = r#"{"is_animated":false,"is_video":false}"#;
|
||||||
let fmt: StickerFormat = serde_json::from_str(json).unwrap();
|
let fmt_flags: StickerFormatFlags = serde_json::from_str(json).unwrap();
|
||||||
assert_eq!(fmt, StickerFormat::Static);
|
assert_eq!(fmt_flags.format(), StickerFormat::Static);
|
||||||
|
|
||||||
let json2 = serde_json::to_string(&fmt).unwrap();
|
let json2 = serde_json::to_string(&fmt_flags).unwrap();
|
||||||
assert_eq!(json, json2);
|
assert_eq!(json, json2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let json = r#"{"is_animated":true,"is_video":false}"#;
|
let json = r#"{"is_animated":true,"is_video":false}"#;
|
||||||
let fmt: StickerFormat = serde_json::from_str(json).unwrap();
|
let fmt_flags: StickerFormatFlags = serde_json::from_str(json).unwrap();
|
||||||
assert_eq!(fmt, StickerFormat::Animated);
|
assert_eq!(fmt_flags.format(), StickerFormat::Animated);
|
||||||
|
|
||||||
let json2 = serde_json::to_string(&fmt).unwrap();
|
let json2 = serde_json::to_string(&fmt_flags).unwrap();
|
||||||
assert_eq!(json, json2);
|
assert_eq!(json, json2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let json = r#"{"is_animated":false,"is_video":true}"#;
|
let json = r#"{"is_animated":false,"is_video":true}"#;
|
||||||
let fmt: StickerFormat = serde_json::from_str(json).unwrap();
|
let fmt_flags: StickerFormatFlags = serde_json::from_str(json).unwrap();
|
||||||
assert_eq!(fmt, StickerFormat::Video);
|
assert_eq!(fmt_flags.format(), StickerFormat::Video);
|
||||||
|
|
||||||
let json2 = serde_json::to_string(&fmt).unwrap();
|
let json2 = serde_json::to_string(&fmt_flags).unwrap();
|
||||||
assert_eq!(json, json2);
|
assert_eq!(json, json2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn wrong_sticker_format_flags_serde() {
|
||||||
{
|
{
|
||||||
let json = r#"{"is_animated":true,"is_video":true}"#;
|
let json = r#"{"is_animated":true,"is_video":true}"#;
|
||||||
let fmt: Result<StickerFormat, _> = serde_json::from_str(json);
|
let fmt_flags: StickerFormatFlags = serde_json::from_str(json).unwrap();
|
||||||
assert!(fmt.is_err());
|
fmt_flags.format();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::ops::Deref;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::{PhotoSize, Sticker, StickerFormat, StickerType};
|
use crate::types::{PhotoSize, Sticker, StickerFormat, StickerFormatFlags, StickerType};
|
||||||
|
|
||||||
/// This object represents a sticker set.
|
/// This object represents a sticker set.
|
||||||
///
|
///
|
||||||
|
@ -20,9 +20,9 @@ pub struct StickerSet {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub kind: StickerType,
|
pub kind: StickerType,
|
||||||
|
|
||||||
/// Sticker format shared by all stickers in this set.
|
/// Sticker format flags shared by all stickers in this set.
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub format: StickerFormat,
|
pub flags: StickerFormatFlags,
|
||||||
|
|
||||||
/// List of all set stickers.
|
/// List of all set stickers.
|
||||||
pub stickers: Vec<Sticker>,
|
pub stickers: Vec<Sticker>,
|
||||||
|
@ -50,36 +50,42 @@ impl Deref for StickerSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StickerSet {
|
impl StickerSet {
|
||||||
|
/// Returns the format of the stickers in this set
|
||||||
|
#[must_use]
|
||||||
|
pub fn format(&self) -> StickerFormat {
|
||||||
|
self.flags.format()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is a "normal" raster sticker.
|
/// Returns `true` is this is a "normal" raster sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_static()`].
|
/// Alias to [`self.format().is_static()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_static()`]: StickerFormat::is_static
|
/// [`self.format().is_static()`]: StickerFormat::is_static
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_static(&self) -> bool {
|
pub fn is_static(&self) -> bool {
|
||||||
self.format.is_static()
|
self.format().is_static()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is an [animated] sticker.
|
/// Returns `true` is this is an [animated] sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_animated()`].
|
/// Alias to [`self.format().is_animated()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_animated()`]: StickerFormat::is_animated
|
/// [`self.format().is_animated()`]: StickerFormat::is_animated
|
||||||
/// [animated]: https://telegram.org/blog/animated-stickers
|
/// [animated]: https://telegram.org/blog/animated-stickers
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_animated(&self) -> bool {
|
pub fn is_animated(&self) -> bool {
|
||||||
self.format.is_animated()
|
self.format().is_animated()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` is this is a [video] sticker.
|
/// Returns `true` is this is a [video] sticker.
|
||||||
///
|
///
|
||||||
/// Alias to [`self.format.is_video()`].
|
/// Alias to [`self.format().is_video()`].
|
||||||
///
|
///
|
||||||
/// [`self.format.is_video()`]: StickerFormat::is_video
|
/// [`self.format().is_video()`]: StickerFormat::is_video
|
||||||
/// [video]: https://telegram.org/blog/video-stickers-better-reactions
|
/// [video]: https://telegram.org/blog/video-stickers-better-reactions
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_video(&self) -> bool {
|
pub fn is_video(&self) -> bool {
|
||||||
self.format.is_video()
|
self.format().is_video()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue