diff --git a/Cargo.lock b/Cargo.lock index 4c8bac8..a48aebe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -622,6 +622,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum_display_style_derive" +version = "0.1.0" +dependencies = [ + "darling", + "quote", + "syn 2.0.99", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1366,6 +1375,7 @@ dependencies = [ "derive_setters", "deunicode", "dirs-next", + "enum_display_style_derive", "human-panic", "indicatif", "indoc", @@ -1764,9 +1774,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] diff --git a/Cargo.toml b/Cargo.toml index a2ca6e7..3169ed5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ rust-version = "1.82.0" exclude = [".github", "CONTRIBUTING.md", "*.log", "tags"] [workspace] -members = ["proc_macros/validate_theme_derive"] +members = ["proc_macros/enum_display_style_derive", "proc_macros/validate_theme_derive"] [dependencies] anyhow = "1.0.68" @@ -64,6 +64,7 @@ paste = "1.0.15" openssl = { version = "0.10.70", features = ["vendored"] } veil = "0.2.0" validate_theme_derive = { path = "proc_macros/validate_theme_derive" } +enum_display_style_derive = { path = "proc_macros/enum_display_style_derive" } [dev-dependencies] assert_cmd = "2.0.16" diff --git a/Makefile b/Makefile index 5f224d4..31fce58 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ default: run .PHONY: test test-cov build run lint lint-fix fmt analyze sonar release delete-tag test: - @cargo test + @cargo test --all ## Run all tests with coverage - `cargo install cargo-tarpaulin` test-cov: diff --git a/proc_macros/enum_display_style_derive/Cargo.toml b/proc_macros/enum_display_style_derive/Cargo.toml new file mode 100644 index 0000000..5c4a7fe --- /dev/null +++ b/proc_macros/enum_display_style_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "enum_display_style_derive" +version = "0.1.0" +edition = "2024" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.39" +syn = "2.0.99" +darling = "0.20.10" diff --git a/proc_macros/enum_display_style_derive/src/lib.rs b/proc_macros/enum_display_style_derive/src/lib.rs new file mode 100644 index 0000000..9d8f360 --- /dev/null +++ b/proc_macros/enum_display_style_derive/src/lib.rs @@ -0,0 +1,77 @@ +mod macro_models; + +use crate::macro_models::DisplayStyleArgs; +use darling::FromVariant; +use quote::quote; +use syn::{Data, DeriveInput, parse_macro_input}; + +/// Derive macro for the EnumDisplayStyle trait. +/// +/// # Example +/// +/// Using default values for the display style: +/// +/// ``` +/// use enum_display_style_derive::EnumDisplayStyle; +/// +/// #[derive(EnumDisplayStyle)] +/// enum Weekend { +/// Saturday, +/// Sunday, +/// } +/// +/// assert_eq!(Weekend::Saturday.to_display_str(), "Saturday"); +/// assert_eq!(Weekend::Sunday.to_display_str(), "Sunday"); +/// +/// ``` +/// +/// Using custom values for the display style: +/// +/// ``` +/// use enum_display_style_derive::EnumDisplayStyle; +/// +/// #[derive(EnumDisplayStyle)] +/// enum MonitorStatus { +/// #[display_style(name = "Monitor Transactions")] +/// Active, +/// #[display_style(name = "Don't Monitor Transactions")] +/// None, +/// } +/// +/// assert_eq!(MonitorStatus::Active.to_display_str(), "Monitor Transactions"); +/// assert_eq!(MonitorStatus::None.to_display_str(), "Don't Monitor Transactions"); +/// ``` +#[proc_macro_derive(EnumDisplayStyle, attributes(display_style))] +pub fn enum_display_style_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let enum_name = &input.ident; + + let mut match_arms = Vec::new(); + + if let Data::Enum(data_enum) = &input.data { + let variants = &data_enum.variants; + + for variant in variants { + let variant_ident = &variant.ident; + let variant_display_name = DisplayStyleArgs::from_variant(variant) + .unwrap() + .name + .unwrap_or_else(|| variant_ident.to_string()); + + match_arms.push(quote! { + #enum_name::#variant_ident => #variant_display_name, + }); + } + } + + quote! { + impl<'a> #enum_name { + pub fn to_display_str(self) -> &'a str { + match self { + #(#match_arms)* + } + } + } + } + .into() +} diff --git a/proc_macros/enum_display_style_derive/src/macro_models.rs b/proc_macros/enum_display_style_derive/src/macro_models.rs new file mode 100644 index 0000000..83354e3 --- /dev/null +++ b/proc_macros/enum_display_style_derive/src/macro_models.rs @@ -0,0 +1,7 @@ +use darling::FromVariant; + +#[derive(Debug, FromVariant)] +#[darling(attributes(display_style))] +pub struct DisplayStyleArgs { + pub name: Option, +} diff --git a/src/models/mod.rs b/src/models/mod.rs index 6e6ceb8..75cb072 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -42,10 +42,6 @@ pub enum Serdeable { Sonarr(SonarrSerdeable), } -pub trait EnumDisplayStyle<'a> { - fn to_display_str(self) -> &'a str; -} - pub trait Scrollable { fn scroll_down(&mut self); fn scroll_up(&mut self); @@ -445,6 +441,21 @@ pub fn strip_non_search_characters(input: &str) -> String { #[macro_export] macro_rules! serde_enum_from { ($enum_name:ident { $($variant:ident($ty:ty),)* }) => { + #[derive(Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)] + #[serde(untagged)] + #[allow(clippy::large_enum_variant)] + pub enum $enum_name { + $( + $variant($ty), + )* + } + + impl From<()> for $enum_name { + fn from(_: ()) -> Self { + $enum_name::Value(serde_json::json!({})) + } + } + $( impl From<$ty> for $enum_name { fn from(value: $ty) -> Self { diff --git a/src/models/radarr_models.rs b/src/models/radarr_models.rs index 0ab50cb..d89af1b 100644 --- a/src/models/radarr_models.rs +++ b/src/models/radarr_models.rs @@ -1,19 +1,19 @@ use std::fmt::{Display, Formatter}; +use crate::{models::HorizontallyScrollableText, serde_enum_from}; use chrono::{DateTime, Utc}; use clap::ValueEnum; use derivative::Derivative; +use enum_display_style_derive::EnumDisplayStyle; use serde::{Deserialize, Serialize}; -use serde_json::{json, Number, Value}; -use strum_macros::EnumIter; - -use crate::{models::HorizontallyScrollableText, serde_enum_from}; +use serde_json::{Number, Value}; +use strum_macros::{Display, EnumIter}; use super::servarr_models::{ DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper, QueueEvent, RootFolder, SecurityConfig, Tag, Update, }; -use super::{EnumDisplayStyle, Serdeable}; +use super::Serdeable; #[cfg(test)] #[path = "radarr_models_tests.rs"] @@ -258,69 +258,44 @@ pub struct MediaInfo { } #[derive( - Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum, + Serialize, + Deserialize, + Default, + PartialEq, + Eq, + Clone, + Copy, + Debug, + EnumIter, + ValueEnum, + Display, + EnumDisplayStyle, )] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum MinimumAvailability { #[default] Announced, + #[display_style(name = "In Cinemas")] InCinemas, Released, + #[display_style(name = "TBA")] Tba, } -impl Display for MinimumAvailability { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let minimum_availability = match self { - MinimumAvailability::Tba => "tba", - MinimumAvailability::Announced => "announced", - MinimumAvailability::InCinemas => "inCinemas", - MinimumAvailability::Released => "released", - }; - write!(f, "{minimum_availability}") - } -} - -impl<'a> EnumDisplayStyle<'a> for MinimumAvailability { - fn to_display_str(self) -> &'a str { - match self { - MinimumAvailability::Tba => "TBA", - MinimumAvailability::Announced => "Announced", - MinimumAvailability::InCinemas => "In Cinemas", - MinimumAvailability::Released => "Released", - } - } -} - -#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum)] +#[derive( + Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum, Display, EnumDisplayStyle, +)] +#[strum(serialize_all = "camelCase")] pub enum MovieMonitor { #[default] + #[display_style(name = "Movie only")] MovieOnly, + #[display_style(name = "Movie and Collection")] MovieAndCollection, None, } -impl Display for MovieMonitor { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let monitor = match self { - MovieMonitor::MovieOnly => "movieOnly", - MovieMonitor::MovieAndCollection => "movieAndCollection", - MovieMonitor::None => "none", - }; - write!(f, "{monitor}") - } -} - -impl<'a> EnumDisplayStyle<'a> for MovieMonitor { - fn to_display_str(self) -> &'a str { - match self { - MovieMonitor::MovieOnly => "Movie only", - MovieMonitor::MovieAndCollection => "Movie and Collection", - MovieMonitor::None => "None", - } - } -} - #[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Movie { @@ -475,49 +450,12 @@ impl Display for RadarrTaskName { } } -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -#[allow(clippy::large_enum_variant)] -pub enum RadarrSerdeable { - Value(Value), - Tag(Tag), - BlocklistResponse(BlocklistResponse), - Collections(Vec), - Credits(Vec), - DiskSpaces(Vec), - DownloadsResponse(DownloadsResponse), - HostConfig(HostConfig), - Indexers(Vec), - IndexerSettings(IndexerSettings), - LogResponse(LogResponse), - Movie(Movie), - MovieHistoryItems(Vec), - Movies(Vec), - QualityProfiles(Vec), - QueueEvents(Vec), - Releases(Vec), - RootFolders(Vec), - SecurityConfig(SecurityConfig), - SystemStatus(SystemStatus), - Tags(Vec), - Tasks(Vec), - Updates(Vec), - AddMovieSearchResults(Vec), - IndexerTestResults(Vec), -} - impl From for Serdeable { fn from(value: RadarrSerdeable) -> Serdeable { Serdeable::Radarr(value) } } -impl From<()> for RadarrSerdeable { - fn from(_: ()) -> Self { - RadarrSerdeable::Value(json!({})) - } -} - serde_enum_from!( RadarrSerdeable { Value(Value), diff --git a/src/models/radarr_models_tests.rs b/src/models/radarr_models_tests.rs index b260344..2a611e8 100644 --- a/src/models/radarr_models_tests.rs +++ b/src/models/radarr_models_tests.rs @@ -11,7 +11,7 @@ mod tests { RadarrSerdeable, RadarrTask, RadarrTaskName, SystemStatus, Tag, Update, }, servarr_models::{HostConfig, Log, LogResponse, QueueEvent, RootFolder, SecurityConfig}, - EnumDisplayStyle, Serdeable, + Serdeable, }; #[test] diff --git a/src/models/sonarr_models.rs b/src/models/sonarr_models.rs index 4033ef5..4e0dbc2 100644 --- a/src/models/sonarr_models.rs +++ b/src/models/sonarr_models.rs @@ -1,13 +1,14 @@ use std::fmt::{Display, Formatter}; +use crate::serde_enum_from; use chrono::{DateTime, Utc}; use clap::ValueEnum; use derivative::Derivative; +use enum_display_style_derive::EnumDisplayStyle; use serde::{Deserialize, Serialize}; -use serde_json::{json, Number, Value}; +use serde_json::{Number, Value}; use strum::EnumIter; - -use crate::serde_enum_from; +use strum_macros::Display; use super::{ radarr_models::IndexerTestResult, @@ -15,7 +16,7 @@ use super::{ DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper, QueueEvent, RootFolder, SecurityConfig, Tag, Update, }, - EnumDisplayStyle, HorizontallyScrollableText, Serdeable, + HorizontallyScrollableText, Serdeable, }; #[cfg(test)] @@ -125,8 +126,21 @@ pub struct DownloadRecord { impl Eq for DownloadRecord {} -#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter)] +#[derive( + Serialize, + Deserialize, + Default, + PartialEq, + Eq, + Clone, + Copy, + Debug, + EnumIter, + Display, + EnumDisplayStyle, +)] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum DownloadStatus { #[default] Unknown, @@ -137,45 +151,11 @@ pub enum DownloadStatus { Failed, Warning, Delay, + #[display_style(name = "Download Client Unavailable")] DownloadClientUnavailable, Fallback, } -impl Display for DownloadStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let download_status = match self { - DownloadStatus::Unknown => "unknown", - DownloadStatus::Queued => "queued", - DownloadStatus::Paused => "paused", - DownloadStatus::Downloading => "downloading", - DownloadStatus::Completed => "completed", - DownloadStatus::Failed => "failed", - DownloadStatus::Warning => "warning", - DownloadStatus::Delay => "delay", - DownloadStatus::DownloadClientUnavailable => "downloadClientUnavailable", - DownloadStatus::Fallback => "fallback", - }; - write!(f, "{download_status}") - } -} - -impl<'a> EnumDisplayStyle<'a> for DownloadStatus { - fn to_display_str(self) -> &'a str { - match self { - DownloadStatus::Unknown => "Unknown", - DownloadStatus::Queued => "Queued", - DownloadStatus::Paused => "Paused", - DownloadStatus::Downloading => "Downloading", - DownloadStatus::Completed => "Completed", - DownloadStatus::Failed => "Failed", - DownloadStatus::Warning => "Warning", - DownloadStatus::Delay => "Delay", - DownloadStatus::DownloadClientUnavailable => "Download Client Unavailable", - DownloadStatus::Fallback => "Fallback", - } - } -} - #[derive(Default, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct DownloadsResponse { @@ -363,74 +343,66 @@ pub struct Series { } #[derive( - Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum, + Serialize, + Deserialize, + Default, + PartialEq, + Eq, + Clone, + Copy, + Debug, + EnumIter, + ValueEnum, + Display, + EnumDisplayStyle, )] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum SeriesMonitor { #[default] + #[display_style(name = "All Episodes")] All, Unknown, + #[display_style(name = "Future Episodes")] Future, + #[display_style(name = "Missing Episodes")] Missing, + #[display_style(name = "Existing Episodes")] Existing, + #[display_style(name = "Only First Season")] FirstSeason, + #[display_style(name = "Only Last Season")] LastSeason, + #[display_style(name = "Only Latest Season")] LatestSeason, + #[display_style(name = "Pilot Episode")] Pilot, + #[display_style(name = "Recent Episodes")] Recent, + #[display_style(name = "Only Specials")] MonitorSpecials, + #[display_style(name = "Not Specials")] UnmonitorSpecials, None, Skip, } -impl Display for SeriesMonitor { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let series_monitor = match self { - SeriesMonitor::Unknown => "unknown", - SeriesMonitor::All => "all", - SeriesMonitor::Future => "future", - SeriesMonitor::Missing => "missing", - SeriesMonitor::Existing => "existing", - SeriesMonitor::FirstSeason => "firstSeason", - SeriesMonitor::LastSeason => "lastSeason", - SeriesMonitor::LatestSeason => "latestSeason", - SeriesMonitor::Pilot => "pilot", - SeriesMonitor::Recent => "recent", - SeriesMonitor::MonitorSpecials => "monitorSpecials", - SeriesMonitor::UnmonitorSpecials => "unmonitorSpecials", - SeriesMonitor::None => "none", - SeriesMonitor::Skip => "skip", - }; - write!(f, "{series_monitor}") - } -} - -impl<'a> EnumDisplayStyle<'a> for SeriesMonitor { - fn to_display_str(self) -> &'a str { - match self { - SeriesMonitor::Unknown => "Unknown", - SeriesMonitor::All => "All Episodes", - SeriesMonitor::Future => "Future Episodes", - SeriesMonitor::Missing => "Missing Episodes", - SeriesMonitor::Existing => "Existing Episodes", - SeriesMonitor::FirstSeason => "Only First Season", - SeriesMonitor::LastSeason => "Only Last Season", - SeriesMonitor::LatestSeason => "Only Latest Season", - SeriesMonitor::Pilot => "Pilot Episode", - SeriesMonitor::Recent => "Recent Episodes", - SeriesMonitor::MonitorSpecials => "Only Specials", - SeriesMonitor::UnmonitorSpecials => "Not Specials", - SeriesMonitor::None => "None", - SeriesMonitor::Skip => "Skip", - } - } -} - #[derive( - Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum, + Serialize, + Deserialize, + Default, + PartialEq, + Eq, + Clone, + Copy, + Debug, + EnumIter, + ValueEnum, + Display, + EnumDisplayStyle, )] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum SeriesType { #[default] Standard, @@ -438,27 +410,6 @@ pub enum SeriesType { Anime, } -impl Display for SeriesType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let series_type = match self { - SeriesType::Standard => "standard", - SeriesType::Daily => "daily", - SeriesType::Anime => "anime", - }; - write!(f, "{series_type}") - } -} - -impl<'a> EnumDisplayStyle<'a> for SeriesType { - fn to_display_str(self) -> &'a str { - match self { - SeriesType::Standard => "Standard", - SeriesType::Daily => "Daily", - SeriesType::Anime => "Anime", - } - } -} - #[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct SeriesStatistics { @@ -478,8 +429,21 @@ pub struct SeriesStatistics { impl Eq for SeriesStatistics {} -#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter)] +#[derive( + Serialize, + Deserialize, + Default, + PartialEq, + Eq, + Clone, + Copy, + Debug, + EnumIter, + Display, + EnumDisplayStyle, +)] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum SeriesStatus { #[default] Continuing, @@ -488,29 +452,6 @@ pub enum SeriesStatus { Deleted, } -impl Display for SeriesStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let series_status = match self { - SeriesStatus::Continuing => "continuing", - SeriesStatus::Ended => "ended", - SeriesStatus::Upcoming => "upcoming", - SeriesStatus::Deleted => "deleted", - }; - write!(f, "{series_status}") - } -} - -impl<'a> EnumDisplayStyle<'a> for SeriesStatus { - fn to_display_str(self) -> &'a str { - match self { - SeriesStatus::Continuing => "Continuing", - SeriesStatus::Ended => "Ended", - SeriesStatus::Upcoming => "Upcoming", - SeriesStatus::Deleted => "Deleted", - } - } -} - #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct SonarrHistoryWrapper { @@ -537,51 +478,29 @@ pub struct SonarrHistoryData { pub relative_path: Option, } -#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] +#[derive( + Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Display, EnumDisplayStyle, +)] #[serde(rename_all = "camelCase")] +#[strum(serialize_all = "camelCase")] pub enum SonarrHistoryEventType { #[default] Unknown, Grabbed, + #[display_style(name = "Series Folder Imported")] SeriesFolderImported, + #[display_style(name = "Download Folder Imported")] DownloadFolderImported, + #[display_style(name = "Download Failed")] DownloadFailed, + #[display_style(name = "Episode File Deleted")] EpisodeFileDeleted, + #[display_style(name = "Episode File Renamed")] EpisodeFileRenamed, + #[display_style(name = "Download Ignored")] DownloadIgnored, } -impl Display for SonarrHistoryEventType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let event_type = match self { - SonarrHistoryEventType::Unknown => "unknown", - SonarrHistoryEventType::Grabbed => "grabbed", - SonarrHistoryEventType::SeriesFolderImported => "seriesFolderImported", - SonarrHistoryEventType::DownloadFolderImported => "downloadFolderImported", - SonarrHistoryEventType::DownloadFailed => "downloadFailed", - SonarrHistoryEventType::EpisodeFileDeleted => "episodeFileDeleted", - SonarrHistoryEventType::EpisodeFileRenamed => "episodeFileRenamed", - SonarrHistoryEventType::DownloadIgnored => "downloadIgnored", - }; - write!(f, "{event_type}") - } -} - -impl<'a> EnumDisplayStyle<'a> for SonarrHistoryEventType { - fn to_display_str(self) -> &'a str { - match self { - SonarrHistoryEventType::Unknown => "Unknown", - SonarrHistoryEventType::Grabbed => "Grabbed", - SonarrHistoryEventType::SeriesFolderImported => "Series Folder Imported", - SonarrHistoryEventType::DownloadFolderImported => "Download Folder Imported", - SonarrHistoryEventType::DownloadFailed => "Download Failed", - SonarrHistoryEventType::EpisodeFileDeleted => "Episode File Deleted", - SonarrHistoryEventType::EpisodeFileRenamed => "Episode File Renamed", - SonarrHistoryEventType::DownloadIgnored => "Download Ignored", - } - } -} - #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct SonarrHistoryItem { @@ -681,52 +600,12 @@ impl Display for SonarrTaskName { } } -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -#[allow(clippy::large_enum_variant)] -pub enum SonarrSerdeable { - AddSeriesSearchResults(Vec), - BlocklistResponse(BlocklistResponse), - DownloadsResponse(DownloadsResponse), - DiskSpaces(Vec), - Episode(Episode), - Episodes(Vec), - EpisodeFiles(Vec), - HostConfig(HostConfig), - IndexerSettings(IndexerSettings), - Indexers(Vec), - IndexerTestResults(Vec), - LanguageProfiles(Vec), - LogResponse(LogResponse), - QualityProfiles(Vec), - QueueEvents(Vec), - Releases(Vec), - RootFolders(Vec), - SecurityConfig(SecurityConfig), - SeriesVec(Vec), - Series(Series), - SonarrHistoryItems(Vec), - SonarrHistoryWrapper(SonarrHistoryWrapper), - SystemStatus(SystemStatus), - Tag(Tag), - Tags(Vec), - Tasks(Vec), - Updates(Vec), - Value(Value), -} - impl From for Serdeable { fn from(value: SonarrSerdeable) -> Serdeable { Serdeable::Sonarr(value) } } -impl From<()> for SonarrSerdeable { - fn from(_: ()) -> Self { - SonarrSerdeable::Value(json!({})) - } -} - serde_enum_from!( SonarrSerdeable { AddSeriesSearchResults(Vec), diff --git a/src/models/sonarr_models_tests.rs b/src/models/sonarr_models_tests.rs index 0c1ea46..be82201 100644 --- a/src/models/sonarr_models_tests.rs +++ b/src/models/sonarr_models_tests.rs @@ -15,7 +15,7 @@ mod tests { SeriesStatus, SeriesType, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease, SonarrSerdeable, SonarrTask, SonarrTaskName, SystemStatus, }, - EnumDisplayStyle, Serdeable, + Serdeable, }; #[test] diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index 5f5f3e1..cdd434f 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -11,7 +11,7 @@ use crate::models::radarr_models::CollectionMovie; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block, diff --git a/src/ui/radarr_ui/collections/edit_collection_ui.rs b/src/ui/radarr_ui/collections/edit_collection_ui.rs index 765bad3..54bab3a 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui.rs @@ -10,7 +10,7 @@ use crate::models::servarr_data::radarr::modals::EditCollectionModal; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::render_selectable_input_box; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; use crate::ui::styles::ManagarrStyle; diff --git a/src/ui/radarr_ui/library/add_movie_ui.rs b/src/ui/radarr_ui/library/add_movie_ui.rs index c3670f9..a7e4608 100644 --- a/src/ui/radarr_ui/library/add_movie_ui.rs +++ b/src/ui/radarr_ui/library/add_movie_ui.rs @@ -12,7 +12,7 @@ use crate::app::radarr::radarr_context_clues::ADD_MOVIE_SEARCH_RESULTS_CONTEXT_C use crate::models::radarr_models::AddMovieSearchResult; use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::ui::radarr_ui::collections::CollectionsUi; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ diff --git a/src/ui/radarr_ui/library/edit_movie_ui.rs b/src/ui/radarr_ui/library/edit_movie_ui.rs index 09ba302..18fc10c 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui.rs @@ -12,7 +12,7 @@ use crate::models::servarr_data::radarr::modals::EditMovieModal; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, EDIT_MOVIE_BLOCKS, MOVIE_DETAILS_BLOCKS, }; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::render_selectable_input_box; use crate::ui::radarr_ui::library::movie_details_ui::MovieDetailsUi; diff --git a/src/ui/sonarr_ui/library/add_series_ui.rs b/src/ui/sonarr_ui/library/add_series_ui.rs index 3d95fbd..34384d0 100644 --- a/src/ui/sonarr_ui/library/add_series_ui.rs +++ b/src/ui/sonarr_ui/library/add_series_ui.rs @@ -12,7 +12,7 @@ use crate::app::sonarr::sonarr_context_clues::ADD_SERIES_SEARCH_RESULTS_CONTEXT_ use crate::models::servarr_data::sonarr::modals::AddSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS}; use crate::models::sonarr_models::AddSeriesSearchResult; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::ui::styles::ManagarrStyle; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block, layout_paragraph_borderless, diff --git a/src/ui/sonarr_ui/library/edit_series_ui.rs b/src/ui/sonarr_ui/library/edit_series_ui.rs index 74095da..0b6fee4 100644 --- a/src/ui/sonarr_ui/library/edit_series_ui.rs +++ b/src/ui/sonarr_ui/library/edit_series_ui.rs @@ -12,7 +12,7 @@ use crate::models::servarr_data::sonarr::modals::EditSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EDIT_SERIES_BLOCKS, SERIES_DETAILS_BLOCKS, }; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::render_selectable_input_box; use crate::ui::styles::ManagarrStyle; diff --git a/src/ui/sonarr_ui/library/mod.rs b/src/ui/sonarr_ui/library/mod.rs index a29ec77..a31482c 100644 --- a/src/ui/sonarr_ui/library/mod.rs +++ b/src/ui/sonarr_ui/library/mod.rs @@ -17,7 +17,7 @@ use crate::{ models::{ servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, LIBRARY_BLOCKS}, sonarr_models::{Series, SeriesStatus}, - EnumDisplayStyle, Route, + Route, }, ui::{ styles::ManagarrStyle, diff --git a/src/ui/sonarr_ui/library/series_details_ui.rs b/src/ui/sonarr_ui/library/series_details_ui.rs index ddeee4e..d4965a7 100644 --- a/src/ui/sonarr_ui/library/series_details_ui.rs +++ b/src/ui/sonarr_ui/library/series_details_ui.rs @@ -12,7 +12,7 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SERIES use crate::models::sonarr_models::{ Season, SeasonStatistics, SonarrHistoryEventType, SonarrHistoryItem, }; -use crate::models::{EnumDisplayStyle, Route}; +use crate::models::Route; use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi; use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi; use crate::ui::sonarr_ui::sonarr_ui_utils::{ diff --git a/tests/integration_test.rs b/tests/integration_test.rs new file mode 100644 index 0000000..277fed7 --- /dev/null +++ b/tests/integration_test.rs @@ -0,0 +1,15 @@ +use enum_display_style_derive::EnumDisplayStyle; +use pretty_assertions::assert_str_eq; + +#[test] +fn test_derive_enum_display_style() { + assert_str_eq!(TestEnum::Test.to_display_str(), "Testing 123"); + assert_str_eq!(TestEnum::Ignored.to_display_str(), "Ignored"); +} + +#[derive(EnumDisplayStyle)] +pub enum TestEnum { + #[display_style(name = "Testing 123")] + Test, + Ignored, +}