From bb32cfdf97a9b080e52b486c263b58fe68da36da Mon Sep 17 00:00:00 2001 From: Marc Plano-Lesay Date: Thu, 22 May 2025 21:57:51 +1000 Subject: [PATCH] feat!: distinguish URLs and hosts BREAKING CHANGE: the configuration for Bitmagnet and Ntfy has changed. Instead of `host`, they now use `url`. --- README.md | 4 +- src/actions/bitmagnet/client.rs | 8 ++-- src/actions/bitmagnet/config.rs | 4 +- src/actions/bitmagnet/validation.rs | 18 ++------- src/config/fixtures/test_config.toml | 6 +-- src/config/lib.rs | 4 +- ...t__config__lib__tests__config_parsing.snap | 39 +++++++++++++++---- src/notifications/ntfy/config.rs | 7 ++-- src/notifications/ntfy/notification.rs | 2 +- src/notifications/ntfy/validation.rs | 17 +++----- 10 files changed, 59 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 2807d05..5e3deac 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,13 @@ download_dir = "/downloads" # Optional # BitMagnet configuration [bitmagnet] enable = true -host = "http://localhost:3333" +url = "http://localhost:3333" # Ntfy configuration [ntfy] enable = true topic = "reddit-magnet" -host = "https://ntfy.sh" +url = "https://ntfy.sh" username = "username" # Optional password = "password" # Optional diff --git a/src/actions/bitmagnet/client.rs b/src/actions/bitmagnet/client.rs index 33c77c1..3cd1b20 100644 --- a/src/actions/bitmagnet/client.rs +++ b/src/actions/bitmagnet/client.rs @@ -20,12 +20,12 @@ impl BitmagnetClient { return Err(eyre!("Bitmagnet action is disabled")); } - let url_str = &config.host; - let base_url = Url::parse(url_str).wrap_err_with(|| format!("Invalid URL: {}", url_str))?; - let client = Client::new(); - Ok(BitmagnetClient { client, base_url }) + Ok(BitmagnetClient { + client, + base_url: config.url.clone(), + }) } /// Submit a magnet link to Bitmagnet diff --git a/src/actions/bitmagnet/config.rs b/src/actions/bitmagnet/config.rs index 3e00e64..bcaee88 100644 --- a/src/actions/bitmagnet/config.rs +++ b/src/actions/bitmagnet/config.rs @@ -1,12 +1,12 @@ use crate::app::Enableable; -use crate::config::types::Host; use serde::{Deserialize, Serialize}; +use url::Url; /// Configuration for the Bitmagnet action #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BitmagnetConfig { pub enable: bool, - pub host: Host, + pub url: Url, } impl Enableable for BitmagnetConfig { diff --git a/src/actions/bitmagnet/validation.rs b/src/actions/bitmagnet/validation.rs index bead367..b0c6e03 100644 --- a/src/actions/bitmagnet/validation.rs +++ b/src/actions/bitmagnet/validation.rs @@ -1,14 +1,9 @@ use crate::actions::bitmagnet::BitmagnetConfig; use crate::config::Validate; -use crate::errors::{self}; use color_eyre::eyre::Result; -use url::Url; impl Validate for BitmagnetConfig { fn validate(&self) -> Result<()> { - Url::parse(&self.host.to_string()) - .map_err(|e| errors::config_error(e, &format!("Invalid URL format: {}", self.host)))?; - Ok(()) } } @@ -16,12 +11,12 @@ impl Validate for BitmagnetConfig { #[cfg(test)] mod tests { use super::*; - use crate::config::types::Host; + use url::Url; fn create_valid_config() -> Result { Ok(BitmagnetConfig { enable: true, - host: Host::try_new("http://localhost:8080")?, + url: Url::parse("http://localhost:8080")?, }) } @@ -36,13 +31,8 @@ mod tests { #[test] fn test_invalid_url() -> Result<()> { - let config = BitmagnetConfig { - enable: true, - host: Host::try_new("not a url")?, - }; - - assert!(config.validate().is_err()); - + // This test is no longer needed as the Url type handles validation + // and will not allow invalid URLs to be created Ok(()) } } diff --git a/src/config/fixtures/test_config.toml b/src/config/fixtures/test_config.toml index d25268d..a0ab661 100644 --- a/src/config/fixtures/test_config.toml +++ b/src/config/fixtures/test_config.toml @@ -1,6 +1,6 @@ [bitmagnet] enable = true -host = "http://localhost:8080" +url = "http://localhost:8080" [transmission] enable = false @@ -13,7 +13,7 @@ download_dir = "/downloads" [ntfy] enable = true topic = "reddit-magnet" -host = "https://ntfy.sh" +url = "https://ntfy.sh" priority = "default" [sources.movies] @@ -25,4 +25,4 @@ tags = ["movies", "hd"] username = "tv_shows_fan" title_filter = "S\\d{2}E\\d{2}" imdb_id = "tt1234567" -tags = ["tv", "series"] \ No newline at end of file +tags = ["tv", "series"] diff --git a/src/config/lib.rs b/src/config/lib.rs index 8e88ec8..8a1af3a 100644 --- a/src/config/lib.rs +++ b/src/config/lib.rs @@ -151,9 +151,9 @@ pub fn get_db_path(args: &Args) -> Result { #[cfg(test)] mod tests { use super::*; - use crate::config::types::Host; use insta::assert_debug_snapshot; use std::path::Path; + use url::Url; /// Helper function to create a valid configuration for testing fn create_valid_config() -> Result { @@ -171,7 +171,7 @@ mod tests { Ok(Config { bitmagnet: Some(BitmagnetConfig { enable: true, - host: Host::try_new("http://localhost:8080")?, + url: Url::parse("http://localhost:8080")?, }), transmission: None, ntfy: None, diff --git a/src/config/snapshots/reddit_magnet__config__lib__tests__config_parsing.snap b/src/config/snapshots/reddit_magnet__config__lib__tests__config_parsing.snap index a715746..3fa349a 100644 --- a/src/config/snapshots/reddit_magnet__config__lib__tests__config_parsing.snap +++ b/src/config/snapshots/reddit_magnet__config__lib__tests__config_parsing.snap @@ -1,15 +1,28 @@ --- source: src/config/lib.rs -assertion_line: 247 expression: config --- Config { bitmagnet: Some( BitmagnetConfig { enable: true, - host: Host( - "http://localhost:8080", - ), + url: Url { + scheme: "http", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "localhost", + ), + ), + port: Some( + 8080, + ), + path: "/", + query: None, + fragment: None, + }, }, ), transmission: Some( @@ -35,9 +48,21 @@ Config { ntfy: Some( NtfyConfig { enable: true, - host: Host( - "https://ntfy.sh", - ), + url: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ntfy.sh", + ), + ), + port: None, + path: "/", + query: None, + fragment: None, + }, username: None, password: None, topic: Topic( diff --git a/src/notifications/ntfy/config.rs b/src/notifications/ntfy/config.rs index 65a68ba..cb857ce 100644 --- a/src/notifications/ntfy/config.rs +++ b/src/notifications/ntfy/config.rs @@ -1,6 +1,7 @@ use crate::app::Enableable; -use crate::config::types::{Host, Password, Topic, Username}; +use crate::config::types::{Password, Topic, Username}; use serde::{Deserialize, Serialize}; +use url::Url; /// Configuration for the ntfy notification service #[derive(Debug, Clone, Serialize, Deserialize)] @@ -9,8 +10,8 @@ pub struct NtfyConfig { #[serde(default)] pub enable: bool, - /// The host URL of the ntfy server - pub host: Host, + /// The URL of the ntfy server + pub url: Url, /// The username for authentication (optional) #[serde(default)] diff --git a/src/notifications/ntfy/notification.rs b/src/notifications/ntfy/notification.rs index e8614a0..3507156 100644 --- a/src/notifications/ntfy/notification.rs +++ b/src/notifications/ntfy/notification.rs @@ -17,7 +17,7 @@ pub struct NtfyNotification { impl NtfyNotification { /// Create a new NtfyNotification instance pub fn new(config: NtfyConfig) -> Result { - let mut builder = dispatcher::builder(config.host.as_str()); + let mut builder = dispatcher::builder(config.url.as_str()); // Add authentication if provided if let (Some(username), Some(password)) = (&config.username, &config.password) { diff --git a/src/notifications/ntfy/validation.rs b/src/notifications/ntfy/validation.rs index 00f6d8f..98bb231 100644 --- a/src/notifications/ntfy/validation.rs +++ b/src/notifications/ntfy/validation.rs @@ -2,14 +2,9 @@ use crate::config::Validate; use crate::errors::{self}; use crate::notifications::ntfy::NtfyConfig; use color_eyre::eyre::Result; -use url::Url; impl Validate for NtfyConfig { fn validate(&self) -> Result<()> { - // Validate URL format - Url::parse(&self.host.to_string()) - .map_err(|e| errors::config_error(e, &format!("Invalid URL format: {}", self.host)))?; - match (self.username.as_ref(), self.password.as_ref()) { (Some(_), None) => { return Err(errors::config_error( @@ -33,12 +28,13 @@ impl Validate for NtfyConfig { #[cfg(test)] mod tests { use super::*; - use crate::config::types::{Host, Password, Topic, Username}; + use crate::config::types::{Password, Topic, Username}; + use url::Url; fn create_valid_config() -> Result { Ok(NtfyConfig { enable: true, - host: Host::try_new("https://ntfy.sh")?, + url: Url::parse("https://ntfy.sh")?, username: None, password: None, topic: Topic::try_new("my-topic")?, @@ -56,11 +52,8 @@ mod tests { #[test] fn test_invalid_url() -> Result<()> { - let mut invalid_config = create_valid_config()?; - invalid_config.host = Host::try_new("not a url")?; - - assert!(invalid_config.validate().is_err()); - + // This test is no longer needed as the Url type handles validation + // and will not allow invalid URLs to be created Ok(()) }