Skip to content

Commit

Permalink
refactor!: merge metadata type fields into one
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-yantsen committed Apr 2, 2023
1 parent 2574ca2 commit 5a790d9
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 72 deletions.
197 changes: 197 additions & 0 deletions crates/plex-api/src/media_container/server/library/metadata_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use serde::{Deserialize, Deserializer};
use serde_plain::derive_fromstr_from_deserialize;
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::str::FromStr;

#[derive(Debug, Clone)]
pub enum MetadataType {
Movie,
Episode,
Photo,
Show,
Artist,
MusicAlbum,
Collection(CollectionMetadataSubtype),
Season,
Track,
Playlist(PlaylistMetadataType),
Clip(ClipMetadataSubtype),
#[cfg(not(feature = "tests_deny_unknown_fields"))]
Unknown,
}

pub(crate) fn deserialize_option_metadata_type<'de, D>(
deserializer: D,
) -> Result<Option<MetadataType>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Helper {
r#type: Option<String>,
subtype: Option<String>,
playlist_type: Option<String>,
extra_type: Option<ExtraType>,
}

#[derive(Debug, Deserialize_repr, Clone, Serialize_repr)]
#[repr(u8)]
enum ExtraType {
Trailer = 1,
DeletedScene = 2,
Interview = 3,
MusicVideo = 4,
BehindTheScenes = 5,
Scene = 6,
LiveMusicVideo = 7,
LyricMusicVideo = 8,
Contert = 9,
Featurette = 10,
Short = 11,
Other = 12,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

let m = dbg!(Helper::deserialize(deserializer)?);

match m.r#type {
Some(metadata_type) => Ok(Some(match metadata_type.as_str() {
"movie" => MetadataType::Movie,
"episode" => MetadataType::Episode,
"photo" => MetadataType::Photo,
"show" => MetadataType::Show,
"artist" => MetadataType::Artist,
"album" => MetadataType::MusicAlbum,
"season" => MetadataType::Season,
"track" => MetadataType::Track,
"collection" => match m.subtype {
Some(subtype) => {
MetadataType::Collection(match CollectionMetadataSubtype::from_str(&subtype) {
Ok(subtype) => subtype,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
Err(_) => CollectionMetadataSubtype::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
Err(_) => return Err(serde::de::Error::unknown_variant("unexpected subtype for collection", &["movie", "show"])),
})
}
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => MetadataType::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
_ => return Err(serde::de::Error::missing_field(
"metadata with `collection` type expects a subtype field present, which is missing",
)),
},
"clip" => match m.subtype {
Some(subtype) => {
MetadataType::Clip(match ClipMetadataSubtype::from_str(&subtype) {
Ok(subtype) => subtype,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
Err(_) => ClipMetadataSubtype::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
Err(_) => return Err(serde::de::Error::unknown_variant(&subtype, &["trailer"])),
})
}
None if m.extra_type.is_some() => MetadataType::Clip(match m.extra_type {
Some(subtype) => match subtype {
ExtraType::Trailer => ClipMetadataSubtype::Trailer,
ExtraType::DeletedScene => ClipMetadataSubtype::DeletedScene,
ExtraType::Interview => ClipMetadataSubtype::Interview,
ExtraType::MusicVideo => ClipMetadataSubtype::MusicVideo,
ExtraType::BehindTheScenes => ClipMetadataSubtype::BehindTheScenes,
ExtraType::Scene => ClipMetadataSubtype::SceneOrSample,
ExtraType::LiveMusicVideo => ClipMetadataSubtype::LiveMusicVideo,
ExtraType::LyricMusicVideo => ClipMetadataSubtype::LyricMusicVideo,
ExtraType::Contert => ClipMetadataSubtype::Concert,
ExtraType::Featurette => ClipMetadataSubtype::Featurette,
ExtraType::Short => ClipMetadataSubtype::Short,
ExtraType::Other => ClipMetadataSubtype::Other,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
ExtraType::Unknown => ClipMetadataSubtype::Unknown,
},
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => ClipMetadataSubtype::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
_ => return Err(serde::de::Error::unknown_variant("empty extra_type", &["trailer"])),
}),
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => MetadataType::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
_ => return Err(serde::de::Error::missing_field(
"metadata with `clip` type expects a subtype field present, which is missing",
)),
},
"playlist" => match m.playlist_type {
Some(subtype) => {
MetadataType::Playlist(match PlaylistMetadataType::from_str(&subtype) {
Ok(subtype) => subtype,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
Err(_) => PlaylistMetadataType::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
Err(_) => return Err(serde::de::Error::unknown_variant(&subtype, &["video", "audio", "photo"])),
})
}
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => MetadataType::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
_ => return Err(serde::de::Error::missing_field(
"metadata with `playlist` type expects a playlist_type field present, which is missing",
)),
},
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => MetadataType::Unknown,
#[cfg(feature = "tests_deny_unknown_fields")]
_ => return Err(serde::de::Error::unknown_variant(&metadata_type, &["movie", "episode", "photo", "show", "artist", "album", "season", "track", "collection", "clip", "playlist"])),
})),
None => Ok(None),
}
}

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum PlaylistMetadataType {
Video,
Audio,
Photo,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

derive_fromstr_from_deserialize!(PlaylistMetadataType);

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum CollectionMetadataSubtype {
Show,
Movie,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

derive_fromstr_from_deserialize!(CollectionMetadataSubtype);

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub enum ClipMetadataSubtype {
Trailer,
DeletedScene,
Interview,
MusicVideo,
BehindTheScenes,
SceneOrSample,
LiveMusicVideo,
LyricMusicVideo,
Concert,
Featurette,
Short,
Other,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

derive_fromstr_from_deserialize!(ClipMetadataSubtype);
52 changes: 4 additions & 48 deletions crates/plex-api/src/media_container/server/library/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod guid;
mod metadata_type;

use crate::media_container::{preferences::Preferences, MediaContainer};
pub use guid::Guid;
pub use metadata_type::*;
use monostate::MustBe;
use serde::{Deserialize, Deserializer, Serialize};
use serde_aux::prelude::{
Expand Down Expand Up @@ -533,39 +535,6 @@ pub struct GrandParentMetadata {
pub grandparent_theme: Option<String>,
}

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum MetadataType {
Movie,
Episode,
Photo,
Show,
Artist,
#[serde(rename = "album")]
MusicAlbum,
Collection,
Season,
Track,
Playlist,
Clip,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

derive_fromstr_from_deserialize!(MetadataType);

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum PlaylistType {
Video,
Audio,
Photo,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

#[derive(Debug, Deserialize, Clone)]
#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -594,17 +563,6 @@ pub struct Chapter {
pub end_time_offset: u64,
}

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum MetadataSubtype {
Trailer,
Show,
Movie,
#[cfg(not(feature = "tests_deny_unknown_fields"))]
#[serde(other)]
Unknown,
}

#[derive(Debug, Deserialize, Clone)]
#[cfg_attr(feature = "tests_deny_unknown_fields", serde(deny_unknown_fields))]
#[serde(rename_all = "camelCase")]
Expand All @@ -615,10 +573,8 @@ pub struct Metadata {
pub guid: Guid,
pub primary_guid: Option<Guid>,

#[serde(rename = "type")]
#[serde(flatten, deserialize_with = "deserialize_option_metadata_type")]
pub metadata_type: Option<MetadataType>,
pub subtype: Option<MetadataSubtype>,
pub playlist_type: Option<PlaylistType>,
pub smart: Option<bool>,
#[serde(default, deserialize_with = "optional_boolish")]
pub allow_sync: Option<bool>,
Expand Down Expand Up @@ -797,7 +753,7 @@ pub struct MetadataMediaContainer {
pub view_group: Option<String>,
pub view_mode: Option<u32>,
pub leaf_count: Option<u32>,
pub playlist_type: Option<PlaylistType>,
pub playlist_type: Option<PlaylistMetadataType>,

#[serde(default, rename = "Directory")]
pub directories: Vec<Value>,
Expand Down
43 changes: 19 additions & 24 deletions crates/plex-api/src/server/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use isahc::AsyncReadResponseExt;
use crate::{
media_container::{
server::library::{
LibraryType, Media as MediaMetadata, Metadata, MetadataMediaContainer, MetadataSubtype,
MetadataType, Part as PartMetadata, PlaylistType, Protocol, SearchType, ServerLibrary,
CollectionMetadataSubtype, LibraryType, Media as MediaMetadata, Metadata,
MetadataMediaContainer, MetadataType, Part as PartMetadata, PlaylistMetadataType,
Protocol, SearchType, ServerLibrary,
},
MediaContainerWrapper,
},
Expand Down Expand Up @@ -687,28 +688,22 @@ impl FromMetadata for Item {
MetadataType::MusicAlbum => MusicAlbum::from_metadata(client, metadata).into(),
MetadataType::Season => Season::from_metadata(client, metadata).into(),
MetadataType::Track => Track::from_metadata(client, metadata).into(),
MetadataType::Clip => Clip::from_metadata(client, metadata).into(),
MetadataType::Collection => match metadata.subtype {
Some(MetadataSubtype::Movie) => {
Collection::<Movie>::from_metadata(client, metadata).into()
}
Some(MetadataSubtype::Show) => {
Collection::<Show>::from_metadata(client, metadata).into()
}
_ => UnknownItem::from_metadata(client, metadata).into(),
},
MetadataType::Playlist => match metadata.playlist_type {
Some(PlaylistType::Video) => {
Playlist::<Video>::from_metadata(client, metadata).into()
}
Some(PlaylistType::Audio) => {
Playlist::<Track>::from_metadata(client, metadata).into()
}
Some(PlaylistType::Photo) => {
Playlist::<Photo>::from_metadata(client, metadata).into()
}
_ => UnknownItem::from_metadata(client, metadata).into(),
},
MetadataType::Clip(_) => Clip::from_metadata(client, metadata).into(),
MetadataType::Collection(CollectionMetadataSubtype::Movie) => {
Collection::<Movie>::from_metadata(client, metadata).into()
}
MetadataType::Collection(CollectionMetadataSubtype::Show) => {
Collection::<Show>::from_metadata(client, metadata).into()
}
MetadataType::Playlist(PlaylistMetadataType::Video) => {
Playlist::<Video>::from_metadata(client, metadata).into()
}
MetadataType::Playlist(PlaylistMetadataType::Audio) => {
Playlist::<Track>::from_metadata(client, metadata).into()
}
MetadataType::Playlist(PlaylistMetadataType::Photo) => {
Playlist::<Photo>::from_metadata(client, metadata).into()
}
#[cfg(not(feature = "tests_deny_unknown_fields"))]
_ => UnknownItem::from_metadata(client, metadata).into(),
}
Expand Down

0 comments on commit 5a790d9

Please sign in to comment.