Merge branch 'develop' into custom-themes
# Conflicts: # Cargo.toml
This commit is contained in:
Generated
+12
-2
@@ -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",
|
||||
]
|
||||
|
||||
+2
-1
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
use darling::FromVariant;
|
||||
|
||||
#[derive(Debug, FromVariant)]
|
||||
#[darling(attributes(display_style))]
|
||||
pub struct DisplayStyleArgs {
|
||||
pub name: Option<String>,
|
||||
}
|
||||
+15
-4
@@ -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 {
|
||||
|
||||
+26
-88
@@ -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<Collection>),
|
||||
Credits(Vec<Credit>),
|
||||
DiskSpaces(Vec<DiskSpace>),
|
||||
DownloadsResponse(DownloadsResponse),
|
||||
HostConfig(HostConfig),
|
||||
Indexers(Vec<Indexer>),
|
||||
IndexerSettings(IndexerSettings),
|
||||
LogResponse(LogResponse),
|
||||
Movie(Movie),
|
||||
MovieHistoryItems(Vec<MovieHistoryItem>),
|
||||
Movies(Vec<Movie>),
|
||||
QualityProfiles(Vec<QualityProfile>),
|
||||
QueueEvents(Vec<QueueEvent>),
|
||||
Releases(Vec<RadarrRelease>),
|
||||
RootFolders(Vec<RootFolder>),
|
||||
SecurityConfig(SecurityConfig),
|
||||
SystemStatus(SystemStatus),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<RadarrTask>),
|
||||
Updates(Vec<Update>),
|
||||
AddMovieSearchResults(Vec<AddMovieSearchResult>),
|
||||
IndexerTestResults(Vec<IndexerTestResult>),
|
||||
}
|
||||
|
||||
impl From<RadarrSerdeable> 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),
|
||||
|
||||
@@ -11,7 +11,7 @@ mod tests {
|
||||
RadarrSerdeable, RadarrTask, RadarrTaskName, SystemStatus, Tag, Update,
|
||||
},
|
||||
servarr_models::{HostConfig, Log, LogResponse, QueueEvent, RootFolder, SecurityConfig},
|
||||
EnumDisplayStyle, Serdeable,
|
||||
Serdeable,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
||||
+81
-202
@@ -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<String>,
|
||||
}
|
||||
|
||||
#[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<AddSeriesSearchResult>),
|
||||
BlocklistResponse(BlocklistResponse),
|
||||
DownloadsResponse(DownloadsResponse),
|
||||
DiskSpaces(Vec<DiskSpace>),
|
||||
Episode(Episode),
|
||||
Episodes(Vec<Episode>),
|
||||
EpisodeFiles(Vec<EpisodeFile>),
|
||||
HostConfig(HostConfig),
|
||||
IndexerSettings(IndexerSettings),
|
||||
Indexers(Vec<Indexer>),
|
||||
IndexerTestResults(Vec<IndexerTestResult>),
|
||||
LanguageProfiles(Vec<Language>),
|
||||
LogResponse(LogResponse),
|
||||
QualityProfiles(Vec<QualityProfile>),
|
||||
QueueEvents(Vec<QueueEvent>),
|
||||
Releases(Vec<SonarrRelease>),
|
||||
RootFolders(Vec<RootFolder>),
|
||||
SecurityConfig(SecurityConfig),
|
||||
SeriesVec(Vec<Series>),
|
||||
Series(Series),
|
||||
SonarrHistoryItems(Vec<SonarrHistoryItem>),
|
||||
SonarrHistoryWrapper(SonarrHistoryWrapper),
|
||||
SystemStatus(SystemStatus),
|
||||
Tag(Tag),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<SonarrTask>),
|
||||
Updates(Vec<Update>),
|
||||
Value(Value),
|
||||
}
|
||||
|
||||
impl From<SonarrSerdeable> 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<AddSeriesSearchResult>),
|
||||
|
||||
@@ -15,7 +15,7 @@ mod tests {
|
||||
SeriesStatus, SeriesType, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease,
|
||||
SonarrSerdeable, SonarrTask, SonarrTaskName, SystemStatus,
|
||||
},
|
||||
EnumDisplayStyle, Serdeable,
|
||||
Serdeable,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
Reference in New Issue
Block a user