ibdl_common/post/
extension.rs

1use std::fmt::{Display, Formatter};
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5
6use super::error::PostError;
7
8/// Enum representing the 8 possible extensions a downloaded post can have.
9#[repr(u8)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
11pub enum Extension {
12    AVIF,
13    JXL,
14    /// The `JPG` variant also encompasses the other extensions a jpeg might have, including `.jpg`, `.jpeg` and `.jfif`
15    JPG,
16    /// The `PNG` variant can also include the rare `.apng` whenever it's present.
17    PNG,
18    WEBP,
19    GIF,
20    WEBM,
21    MP4,
22    /// Pixiv Ugoira is usually downloaded as a zip file with all frames without any additional metadata.
23    Ugoira,
24    /// Used for any file whose extension is unknown or not currently supported by this library.
25    Unknown,
26}
27
28impl Extension {
29    /// Naive and simple way of recognizing the extension of a post to use in [`Post`](crate::post::Post). This function never fails.
30    pub fn guess_format(s: &str) -> Self {
31        let uu = Self::from_str(s);
32        if uu.is_err() {
33            return Self::Unknown;
34        }
35        uu.unwrap()
36    }
37
38    pub const fn is_video(&self) -> bool {
39        matches!(self, Self::GIF | Self::WEBM | Self::MP4 | Self::Ugoira)
40    }
41}
42
43impl FromStr for Extension {
44    type Err = PostError;
45
46    fn from_str(s: &str) -> Result<Self, Self::Err> {
47        match s.to_lowercase().as_str() {
48            "jpg" | "jpeg" | "jfif" => Ok(Self::JPG),
49            "png" | "apng" => Ok(Self::PNG),
50            "webp" => Ok(Self::WEBP),
51            "webm" => Ok(Self::WEBM),
52            "mp4" => Ok(Self::MP4),
53            "gif" => Ok(Self::GIF),
54            "zip" => Ok(Self::Ugoira),
55            "jxl" => Ok(Self::JXL),
56            "avif" => Ok(Self::AVIF),
57            _ => Err(PostError::UnknownExtension {
58                message: s.to_string(),
59            }),
60        }
61    }
62}
63
64impl Display for Extension {
65    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66        match self {
67            Self::JPG => write!(f, "jpg"),
68            Self::PNG => write!(f, "png"),
69            Self::WEBP => write!(f, "webp"),
70            Self::GIF => write!(f, "gif"),
71            Self::WEBM => write!(f, "webm"),
72            Self::MP4 => write!(f, "mp4"),
73            Self::Ugoira => write!(f, "zip"),
74            Self::Unknown => write!(f, "bin"),
75            Self::AVIF => write!(f, "avif"),
76            Self::JXL => write!(f, "jxl"),
77        }
78    }
79}