1use crate::{
2 ids::{EpisodeID, MovieID, SeasonID, SeriesID},
3 media_type::VideoMediaType,
4};
5use uuid::Uuid;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[cfg_attr(
10 feature = "rkyv",
11 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
12)]
13#[cfg_attr(feature = "rkyv", rkyv(derive(Debug, PartialEq, Eq, Hash)))]
14pub enum MediaID {
15 Movie(MovieID),
16 Series(SeriesID),
17 Season(SeasonID),
18 Episode(EpisodeID),
19}
20
21impl Default for MediaID {
22 fn default() -> Self {
23 MediaID::Movie(MovieID(Uuid::now_v7()))
24 }
25}
26
27impl From<(Uuid, VideoMediaType)> for MediaID {
28 fn from(v: (Uuid, VideoMediaType)) -> Self {
29 match v.1 {
30 VideoMediaType::Movie => MediaID::Movie(v.0.into()),
31 VideoMediaType::Series => MediaID::Series(v.0.into()),
32 VideoMediaType::Season => MediaID::Season(v.0.into()),
33 VideoMediaType::Episode => MediaID::Episode(v.0.into()),
34 }
35 }
36}
37
38impl MediaID {
39 pub fn new(media_type: VideoMediaType) -> MediaID {
40 match media_type {
41 VideoMediaType::Movie => MediaID::Movie(MovieID(Uuid::now_v7())),
42 VideoMediaType::Series => MediaID::Series(SeriesID(Uuid::now_v7())),
43 VideoMediaType::Season => MediaID::Season(SeasonID(Uuid::now_v7())),
44 VideoMediaType::Episode => {
45 MediaID::Episode(EpisodeID(Uuid::now_v7()))
46 }
47 }
48 }
49
50 pub fn as_uuid(&self) -> &Uuid {
51 match &self {
52 MediaID::Movie(movie_id) => movie_id.as_uuid(),
53 MediaID::Series(series_id) => series_id.as_uuid(),
54 MediaID::Season(season_id) => season_id.as_uuid(),
55 MediaID::Episode(episode_id) => episode_id.as_uuid(),
56 }
57 }
58
59 pub fn eq_movie(&self, other: &MovieID) -> bool {
60 match (self, other) {
61 (MediaID::Movie(MovieID(a)), MovieID(b)) => a == b,
62 _ => false,
63 }
64 }
65 pub fn eq_series(&self, other: &SeriesID) -> bool {
66 match (self, other) {
67 (MediaID::Series(SeriesID(a)), SeriesID(b)) => a == b,
68 _ => false,
69 }
70 }
71 pub fn eq_episode(&self, other: &EpisodeID) -> bool {
72 match (self, other) {
73 (MediaID::Episode(EpisodeID(a)), EpisodeID(b)) => a == b,
74 _ => false,
75 }
76 }
77}
78impl std::fmt::Display for MediaID {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 match self {
81 MediaID::Movie(id) => write!(f, "Movie({})", id.as_str()),
82 MediaID::Series(id) => write!(f, "Series({})", id.as_str()),
83 MediaID::Season(id) => write!(f, "Season({})", id.as_str()),
84 MediaID::Episode(id) => write!(f, "Episode({})", id.as_str()),
85 }
86 }
87}
88
89impl From<MovieID> for MediaID {
90 fn from(id: MovieID) -> Self {
91 MediaID::Movie(id)
92 }
93}
94
95impl From<SeriesID> for MediaID {
96 fn from(id: SeriesID) -> Self {
97 MediaID::Series(id)
98 }
99}
100
101impl From<SeasonID> for MediaID {
102 fn from(id: SeasonID) -> Self {
103 MediaID::Season(id)
104 }
105}
106
107impl From<EpisodeID> for MediaID {
108 fn from(id: EpisodeID) -> Self {
109 MediaID::Episode(id)
110 }
111}
112
113#[cfg(feature = "rkyv")]
114mod archived {
115 use super::*;
116 use crate::{
117 ids::{
118 ArchivedEpisodeID, ArchivedMovieID, ArchivedSeasonID,
119 ArchivedSeriesID,
120 },
121 media::{ArchivedMedia, ArchivedMovieReference},
122 };
123 use rkyv::rancor::Error;
124 use rkyv::{boxed::ArchivedBox, deserialize};
125
126 impl ArchivedMediaID {
127 pub fn eq_movie(&self, other: &ArchivedMovieID) -> bool {
128 matches!(
129 (self, other),
130 (
131 ArchivedMediaID::Movie(ArchivedMovieID(a)),
132 ArchivedMovieID(b)
133 ) if a == b
134 )
135 }
136
137 pub fn eq_series(&self, other: &ArchivedSeriesID) -> bool {
138 matches!(
139 (self, other),
140 (
141 ArchivedMediaID::Series(ArchivedSeriesID(a)),
142 ArchivedSeriesID(b)
143 ) if a == b
144 )
145 }
146
147 pub fn eq_episode(&self, other: &ArchivedEpisodeID) -> bool {
148 matches!(
149 (self, other),
150 (
151 ArchivedMediaID::Episode(ArchivedEpisodeID(a)),
152 ArchivedEpisodeID(b)
153 ) if a == b
154 )
155 }
156 }
157
158 impl From<ArchivedMedia> for ArchivedBox<ArchivedMovieReference> {
159 fn from(med_ref: ArchivedMedia) -> Self {
160 match med_ref {
161 ArchivedMedia::Movie(data) => data,
162 _ => panic!(
163 "Cannot convert non-movie reference to movie reference"
164 ),
165 }
166 }
167 }
168
169 impl From<ArchivedMovieID> for ArchivedMediaID {
170 fn from(id: ArchivedMovieID) -> Self {
171 ArchivedMediaID::Movie(id)
172 }
173 }
174
175 impl From<ArchivedSeriesID> for ArchivedMediaID {
176 fn from(id: ArchivedSeriesID) -> Self {
177 ArchivedMediaID::Series(id)
178 }
179 }
180
181 impl From<ArchivedSeasonID> for ArchivedMediaID {
182 fn from(id: ArchivedSeasonID) -> Self {
183 ArchivedMediaID::Season(id)
184 }
185 }
186
187 impl From<ArchivedEpisodeID> for ArchivedMediaID {
188 fn from(id: ArchivedEpisodeID) -> Self {
189 ArchivedMediaID::Episode(id)
190 }
191 }
192
193 impl From<ArchivedMovieID> for MediaID {
194 fn from(id: ArchivedMovieID) -> Self {
195 let id = deserialize::<MovieID, Error>(&id).unwrap();
196 MediaID::Movie(id)
197 }
198 }
199
200 impl From<ArchivedSeriesID> for MediaID {
201 fn from(id: ArchivedSeriesID) -> Self {
202 let id = deserialize::<SeriesID, Error>(&id).unwrap();
203 MediaID::Series(id)
204 }
205 }
206
207 impl From<ArchivedSeasonID> for MediaID {
208 fn from(id: ArchivedSeasonID) -> Self {
209 let id = deserialize::<SeasonID, Error>(&id).unwrap();
210 MediaID::Season(id)
211 }
212 }
213
214 impl From<ArchivedEpisodeID> for MediaID {
215 fn from(id: ArchivedEpisodeID) -> Self {
216 let id = deserialize::<EpisodeID, Error>(&id).unwrap();
217 MediaID::Episode(id)
218 }
219 }
220}