From 836d53f7991a5ca8e6ade68fd459468fdffa439e Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Tue, 25 Apr 2023 19:24:35 +0200 Subject: [PATCH] dev: fix clippy warnings for: src/config.rs --- src/config.rs | 180 +++++++++++++++++--------- src/routes/settings.rs | 6 +- tests/common/contexts/settings/mod.rs | 5 +- tests/environments/app_starter.rs | 10 +- tests/environments/isolated.rs | 9 +- 5 files changed, 134 insertions(+), 76 deletions(-) diff --git a/src/config.rs b/src/config.rs index 24fa6201..5a95ff2f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,6 +11,14 @@ pub struct Website { pub name: String, } +impl Default for Website { + fn default() -> Self { + Self { + name: "Torrust".to_string(), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TrackerMode { // todo: use https://crates.io/crates/torrust-tracker-primitives @@ -20,6 +28,12 @@ pub enum TrackerMode { PrivateWhitelisted, } +impl Default for TrackerMode { + fn default() -> Self { + Self::Public + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Tracker { pub url: String, @@ -29,6 +43,18 @@ pub struct Tracker { pub token_valid_seconds: u64, } +impl Default for Tracker { + fn default() -> Self { + Self { + url: "udp://localhost:6969".to_string(), + mode: TrackerMode::default(), + api_url: "http://localhost:1212".to_string(), + token: "MyAccessToken".to_string(), + token_valid_seconds: 7_257_600, + } + } +} + /// Port 0 means that the OS will choose a random free port. pub const FREE_PORT: u16 = 0; @@ -38,6 +64,15 @@ pub struct Network { pub base_url: Option, } +impl Default for Network { + fn default() -> Self { + Self { + port: 3000, + base_url: None, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum EmailOnSignup { Required, @@ -45,6 +80,12 @@ pub enum EmailOnSignup { None, } +impl Default for EmailOnSignup { + fn default() -> Self { + Self::Optional + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Auth { pub email_on_signup: EmailOnSignup, @@ -53,12 +94,32 @@ pub struct Auth { pub secret_key: String, } +impl Default for Auth { + fn default() -> Self { + Self { + email_on_signup: EmailOnSignup::default(), + min_password_length: 6, + max_password_length: 64, + secret_key: "MaxVerstappenWC2021".to_string(), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Database { pub connect_url: String, pub torrent_info_update_interval: u64, } +impl Default for Database { + fn default() -> Self { + Self { + connect_url: "sqlite://data.db?mode=rwc".to_string(), + torrent_info_update_interval: 3600, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Mail { pub email_verification_enabled: bool, @@ -70,6 +131,21 @@ pub struct Mail { pub port: u16, } +impl Default for Mail { + fn default() -> Self { + Self { + email_verification_enabled: false, + from: "example@email.com".to_string(), + reply_to: "noreply@email.com".to_string(), + username: String::default(), + password: String::default(), + server: String::default(), + port: 25, + } + } +} + +#[allow(clippy::module_name_repetitions)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ImageCache { pub max_request_timeout_ms: u64, @@ -85,8 +161,29 @@ pub struct Api { pub max_torrent_page_size: u8, } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AppConfiguration { +impl Default for Api { + fn default() -> Self { + Self { + default_torrent_page_size: 10, + max_torrent_page_size: 30, + } + } +} + +impl Default for ImageCache { + fn default() -> Self { + Self { + max_request_timeout_ms: 1000, + capacity: 128_000_000, + entry_size_limit: 4_000_000, + user_quota_period_seconds: 3600, + user_quota_bytes: 64_000_000, + } + } +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct TorrustBackend { pub website: Website, pub tracker: Tracker, pub net: Network, @@ -97,67 +194,16 @@ pub struct AppConfiguration { pub api: Api, } -impl Default for AppConfiguration { - fn default() -> Self { - Self { - website: Website { - name: "Torrust".to_string(), - }, - tracker: Tracker { - url: "udp://localhost:6969".to_string(), - mode: TrackerMode::Public, - api_url: "http://localhost:1212".to_string(), - token: "MyAccessToken".to_string(), - token_valid_seconds: 7_257_600, - }, - net: Network { - port: 3000, - base_url: None, - }, - auth: Auth { - email_on_signup: EmailOnSignup::Optional, - min_password_length: 6, - max_password_length: 64, - secret_key: "MaxVerstappenWC2021".to_string(), - }, - database: Database { - connect_url: "sqlite://data.db?mode=rwc".to_string(), - torrent_info_update_interval: 3600, - }, - mail: Mail { - email_verification_enabled: false, - from: "example@email.com".to_string(), - reply_to: "noreply@email.com".to_string(), - username: String::new(), - password: String::new(), - server: String::new(), - port: 25, - }, - image_cache: ImageCache { - max_request_timeout_ms: 1000, - capacity: 128_000_000, - entry_size_limit: 4_000_000, - user_quota_period_seconds: 3600, - user_quota_bytes: 64_000_000, - }, - api: Api { - default_torrent_page_size: 10, - max_torrent_page_size: 30, - }, - } - } -} - #[derive(Debug)] pub struct Configuration { - pub settings: RwLock, + pub settings: RwLock, pub config_path: Option, } impl Default for Configuration { - fn default() -> Self { - Self { - settings: RwLock::new(AppConfiguration::default()), + fn default() -> Configuration { + Configuration { + settings: RwLock::new(TorrustBackend::default()), config_path: None, } } @@ -165,6 +211,11 @@ impl Default for Configuration { impl Configuration { /// Loads the configuration from the configuration file. + /// + /// # Errors + /// + /// This function will return an error no configuration in the `CONFIG_PATH` exists, and a new file is is created. + /// This function will return an error if the `config` is not a valid `TorrustConfig` document. pub async fn load_from_file(config_path: &str) -> Result { let config_builder = Config::builder(); @@ -183,7 +234,7 @@ impl Configuration { )); } - let torrust_config: AppConfiguration = match config.try_deserialize() { + let torrust_config: TorrustBackend = match config.try_deserialize() { Ok(data) => Ok(data), Err(e) => Err(ConfigError::Message(format!("Errors while processing config: {}.", e))), }?; @@ -207,7 +258,7 @@ impl Configuration { let config_builder = Config::builder() .add_source(File::from_str(&config_toml, FileFormat::Toml)) .build()?; - let torrust_config: AppConfiguration = config_builder.try_deserialize()?; + let torrust_config: TorrustBackend = config_builder.try_deserialize()?; Ok(Configuration { settings: RwLock::new(torrust_config), config_path: None, @@ -219,6 +270,7 @@ impl Configuration { } } + /// Returns the save to file of this [`Configuration`]. pub async fn save_to_file(&self, config_path: &str) { let settings = self.settings.read().await; @@ -229,13 +281,17 @@ impl Configuration { fs::write(config_path, toml_string).expect("Could not write to file!"); } - /// Updates the settings and saves them to the configuration file. + /// Update the settings file based upon a supplied `new_settings`. + /// + /// # Errors + /// + /// Todo: Make an error if the save fails. /// /// # Panics /// /// Will panic if the configuration file path is not defined. That happens /// when the configuration was loaded from the environment variable. - pub async fn update_settings(&self, new_settings: AppConfiguration) { + pub async fn update_settings(&self, new_settings: TorrustBackend) -> Result<(), ()> { match &self.config_path { Some(config_path) => { let mut settings = self.settings.write().await; @@ -244,6 +300,8 @@ impl Configuration { drop(settings); let _ = self.save_to_file(config_path).await; + + Ok(()) } None => panic!( "Cannot update settings when the config file path is not defined. For example: when it's loaded from env var." diff --git a/src/routes/settings.rs b/src/routes/settings.rs index e2b6849f..65dd0716 100644 --- a/src/routes/settings.rs +++ b/src/routes/settings.rs @@ -1,7 +1,7 @@ use actix_web::{web, HttpRequest, HttpResponse, Responder}; use crate::common::WebAppData; -use crate::config::AppConfiguration; +use crate::config; use crate::errors::{ServiceError, ServiceResult}; use crate::models::response::OkResponse; @@ -27,7 +27,7 @@ pub async fn get_settings(req: HttpRequest, app_data: WebAppData) -> ServiceResu return Err(ServiceError::Unauthorized); } - let settings: tokio::sync::RwLockReadGuard = app_data.cfg.settings.read().await; + let settings: tokio::sync::RwLockReadGuard = app_data.cfg.settings.read().await; Ok(HttpResponse::Ok().json(OkResponse { data: &*settings })) } @@ -57,7 +57,7 @@ pub async fn get_site_name(app_data: WebAppData) -> ServiceResult, + payload: web::Json, app_data: WebAppData, ) -> ServiceResult { // check for user diff --git a/tests/common/contexts/settings/mod.rs b/tests/common/contexts/settings/mod.rs index 4e4f1643..604297f4 100644 --- a/tests/common/contexts/settings/mod.rs +++ b/tests/common/contexts/settings/mod.rs @@ -3,9 +3,8 @@ pub mod responses; use serde::{Deserialize, Serialize}; use torrust_index_backend::config::{ - Api as DomainApi, AppConfiguration as DomainSettings, Auth as DomainAuth, Database as DomainDatabase, - ImageCache as DomainImageCache, Mail as DomainMail, Network as DomainNetwork, Tracker as DomainTracker, - Website as DomainWebsite, + Api as DomainApi, Auth as DomainAuth, Database as DomainDatabase, ImageCache as DomainImageCache, Mail as DomainMail, + Network as DomainNetwork, TorrustBackend as DomainSettings, Tracker as DomainTracker, Website as DomainWebsite, }; #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] diff --git a/tests/environments/app_starter.rs b/tests/environments/app_starter.rs index 55cbb355..251f0481 100644 --- a/tests/environments/app_starter.rs +++ b/tests/environments/app_starter.rs @@ -2,12 +2,12 @@ use std::net::SocketAddr; use log::info; use tokio::sync::{oneshot, RwLock}; -use torrust_index_backend::app; -use torrust_index_backend::config::{AppConfiguration, Configuration}; +use torrust_index_backend::config::Configuration; +use torrust_index_backend::{app, config}; /// It launches the app and provides a way to stop it. pub struct AppStarter { - configuration: AppConfiguration, + configuration: config::TorrustBackend, config_path: Option, /// The application binary state (started or not): /// - `None`: if the app is not started, @@ -17,7 +17,7 @@ pub struct AppStarter { impl AppStarter { #[must_use] - pub fn with_custom_configuration(configuration: AppConfiguration, config_path: Option) -> Self { + pub fn with_custom_configuration(configuration: config::TorrustBackend, config_path: Option) -> Self { Self { configuration, config_path, @@ -75,7 +75,7 @@ impl AppStarter { } #[must_use] - pub fn server_configuration(&self) -> AppConfiguration { + pub fn server_configuration(&self) -> config::TorrustBackend { self.configuration.clone() } diff --git a/tests/environments/isolated.rs b/tests/environments/isolated.rs index 943497ee..e619e191 100644 --- a/tests/environments/isolated.rs +++ b/tests/environments/isolated.rs @@ -1,5 +1,6 @@ use tempfile::TempDir; -use torrust_index_backend::config::{AppConfiguration, FREE_PORT}; +use torrust_index_backend::config; +use torrust_index_backend::config::FREE_PORT; use super::app_starter::AppStarter; use crate::common::random; @@ -44,7 +45,7 @@ impl TestEnv { /// Provides the whole server configuration. #[must_use] - pub fn server_configuration(&self) -> AppConfiguration { + pub fn server_configuration(&self) -> config::TorrustBackend { self.app_starter.server_configuration() } @@ -67,8 +68,8 @@ impl Default for TestEnv { } /// Provides a configuration with ephemeral data for testing. -fn ephemeral(temp_dir: &TempDir) -> AppConfiguration { - let mut configuration = AppConfiguration::default(); +fn ephemeral(temp_dir: &TempDir) -> config::TorrustBackend { + let mut configuration = config::TorrustBackend::default(); // Ephemeral API port configuration.net.port = FREE_PORT;