Skip to content

Commit

Permalink
dev: fix clippy warnings for: src/config.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
da2ce7 committed May 10, 2023
1 parent a741a22 commit 836d53f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 76 deletions.
180 changes: 119 additions & 61 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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;

Expand All @@ -38,13 +64,28 @@ pub struct Network {
pub base_url: Option<String>,
}

impl Default for Network {
fn default() -> Self {
Self {
port: 3000,
base_url: None,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EmailOnSignup {
Required,
Optional,
None,
}

impl Default for EmailOnSignup {
fn default() -> Self {
Self::Optional
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Auth {
pub email_on_signup: EmailOnSignup,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -97,74 +194,28 @@ 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<AppConfiguration>,
pub settings: RwLock<TorrustBackend>,
pub config_path: Option<String>,
}

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,
}
}
}

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<Configuration, ConfigError> {
let config_builder = Config::builder();

Expand All @@ -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))),
}?;
Expand All @@ -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,
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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."
Expand Down
6 changes: 3 additions & 3 deletions src/routes/settings.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -27,7 +27,7 @@ pub async fn get_settings(req: HttpRequest, app_data: WebAppData) -> ServiceResu
return Err(ServiceError::Unauthorized);
}

let settings: tokio::sync::RwLockReadGuard<AppConfiguration> = app_data.cfg.settings.read().await;
let settings: tokio::sync::RwLockReadGuard<config::TorrustBackend> = app_data.cfg.settings.read().await;

Ok(HttpResponse::Ok().json(OkResponse { data: &*settings }))
}
Expand Down Expand Up @@ -57,7 +57,7 @@ pub async fn get_site_name(app_data: WebAppData) -> ServiceResult<impl Responder
/// - The settings could not be updated because they were loaded from env vars.
pub async fn update_settings_handler(
req: HttpRequest,
payload: web::Json<AppConfiguration>,
payload: web::Json<config::TorrustBackend>,
app_data: WebAppData,
) -> ServiceResult<impl Responder> {
// check for user
Expand Down
5 changes: 2 additions & 3 deletions tests/common/contexts/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
10 changes: 5 additions & 5 deletions tests/environments/app_starter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
/// The application binary state (started or not):
/// - `None`: if the app is not started,
Expand All @@ -17,7 +17,7 @@ pub struct AppStarter {

impl AppStarter {
#[must_use]
pub fn with_custom_configuration(configuration: AppConfiguration, config_path: Option<String>) -> Self {
pub fn with_custom_configuration(configuration: config::TorrustBackend, config_path: Option<String>) -> Self {
Self {
configuration,
config_path,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl AppStarter {
}

#[must_use]
pub fn server_configuration(&self) -> AppConfiguration {
pub fn server_configuration(&self) -> config::TorrustBackend {
self.configuration.clone()
}

Expand Down
Loading

0 comments on commit 836d53f

Please sign in to comment.