1use crate::domain::{animation::AnimationKind, audio::AudioKind};
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
9#[serde(tag = "media_kind")]
10#[serde(rename_all = "camelCase")]
11pub enum MediaGroupKind {
12 Audio,
14
15 Image,
17
18 Animation,
20
21 Pdf,
23}
24
25impl MediaGroupKind {
26 #[must_use]
28 pub const fn to_str(self) -> &'static str {
29 match self {
30 Self::Audio => "audio",
31 Self::Image => "image",
32 Self::Animation => "animation",
33 Self::Pdf => "pdf",
34 }
35 }
36}
37
38#[derive(Debug, Copy, Clone)]
40pub enum PngImageFile {
41 Original,
43
44 Resized,
46
47 Thumbnail,
49}
50
51#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq)]
53#[cfg_attr(feature = "backend", derive(sqlx::Type))]
54#[repr(i16)]
55pub enum MediaLibrary {
56 Global = 0,
58
59 User = 1,
61
62 Web = 2,
64}
65
66impl MediaLibrary {
67 #[must_use]
69 pub const fn to_str(self) -> &'static str {
70 match self {
71 Self::Global => "global",
72 Self::User => "user",
73 Self::Web => "web",
74 }
75 }
76}
77
78impl std::str::FromStr for MediaLibrary {
79 type Err = anyhow::Error;
80
81 fn from_str(s: &str) -> Result<Self, Self::Err> {
82 match s {
83 "global" => Ok(Self::Global),
84 "user" => Ok(Self::User),
85 "web" => Ok(Self::Web),
86 _ => Err(anyhow::anyhow!("media type not recognized")),
87 }
88 }
89}
90
91#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
93pub enum MediaKind {
94 Animation(AnimationKind),
96
97 Image,
99
100 Audio(AudioKind),
102
103 Pdf,
105}
106
107#[derive(Copy, Clone, Debug)]
110pub enum FileKind {
111 AnimationGif,
113
114 ImagePng(PngImageFile),
116
117 AudioMp3,
120
121 DocumentPdf,
123}
124
125impl FileKind {
126 #[must_use]
128 pub const fn content_type(self) -> &'static str {
129 match self {
130 Self::AnimationGif => "image/gif",
131 Self::ImagePng(_) => "image/png",
132 Self::AudioMp3 => "audio/mp3",
133 Self::DocumentPdf => "application/pdf",
134 }
135 }
136
137 #[must_use]
138 const fn suffix(self) -> &'static str {
139 match self {
140 Self::AnimationGif => "animation.gif",
141 Self::ImagePng(PngImageFile::Original) => "original.png",
142 Self::ImagePng(PngImageFile::Thumbnail) => "thumbnail.png",
143 Self::ImagePng(PngImageFile::Resized) => "resized.png",
144 Self::AudioMp3 => "audio.mp3",
145 Self::DocumentPdf => "document.pdf",
146 }
147 }
148}
149
150impl std::str::FromStr for FileKind {
151 type Err = anyhow::Error;
152
153 fn from_str(s: &str) -> Result<Self, Self::Err> {
154 match s {
155 "animation.gif" => Ok(Self::AnimationGif),
156 "original.png" => Ok(Self::ImagePng(PngImageFile::Original)),
157 "thumbnail.png" => Ok(Self::ImagePng(PngImageFile::Thumbnail)),
158 "resized.png" => Ok(Self::ImagePng(PngImageFile::Resized)),
159 "audio.mp3" => Ok(Self::AudioMp3),
160 "document.pdf" => Ok(Self::DocumentPdf),
161 _ => Err(anyhow::anyhow!("media type not recognized")),
162 }
163 }
164}
165
166#[derive(Deserialize, Serialize)]
170#[allow(dead_code)]
171pub struct MediaKey {
172 pub media_library: MediaLibrary,
174 pub id: Uuid,
176 pub content_type: String,
179}
180
181#[must_use]
184pub fn media_key(library: MediaLibrary, id: Uuid, file_kind: FileKind) -> String {
185 format!(
186 "media/{}/{}/{}",
187 library.to_str(),
188 id.hyphenated(),
189 file_kind.suffix()
190 )
191}