diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config/default.rs | 4 | ||||
-rw-r--r-- | src/config/definitions.rs | 59 | ||||
-rw-r--r-- | src/config/file_system.rs | 91 | ||||
-rw-r--r-- | src/config/mod.rs | 5 |
4 files changed, 105 insertions, 54 deletions
diff --git a/src/config/default.rs b/src/config/default.rs index e99b255..8eedb18 100644 --- a/src/config/default.rs +++ b/src/config/default.rs @@ -54,13 +54,13 @@ pub mod select { } pub mod watch { - pub fn local_comments_length() -> i64 { + pub fn local_comments_length() -> usize { 1000 } } pub mod update { - pub fn max_backlog() -> i64 { + pub fn max_backlog() -> u32 { 20 } } diff --git a/src/config/definitions.rs b/src/config/definitions.rs new file mode 100644 index 0000000..d37e6da --- /dev/null +++ b/src/config/definitions.rs @@ -0,0 +1,59 @@ +// yt - A fully featured command line YouTube client +// +// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de> +// SPDX-License-Identifier: GPL-3.0-or-later +// +// This file is part of Yt. +// +// You should have received a copy of the License along with this program. +// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +use std::path::PathBuf; + +use serde::Deserialize; + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct ConfigFile { + pub select: Option<SelectConfig>, + pub watch: Option<WatchConfig>, + pub paths: Option<PathsConfig>, + pub download: Option<DownloadConfig>, + pub update: Option<UpdateConfig>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone, Copy)] +#[serde(deny_unknown_fields)] +pub struct UpdateConfig { + pub max_backlog: Option<u32>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone)] +#[serde(deny_unknown_fields)] +pub struct DownloadConfig { + /// This will then be converted to an u64 + pub max_cache_size: Option<String>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone)] +#[serde(deny_unknown_fields)] +pub struct SelectConfig { + pub playback_speed: Option<f64>, + pub subtitle_langs: Option<String>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone, Copy)] +#[serde(deny_unknown_fields)] +pub struct WatchConfig { + pub local_comments_length: Option<usize>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone)] +#[serde(deny_unknown_fields)] +pub struct PathsConfig { + pub download_dir: Option<PathBuf>, + pub mpv_config_path: Option<PathBuf>, + pub mpv_input_path: Option<PathBuf>, + pub database_path: Option<PathBuf>, + pub last_selection_path: Option<PathBuf>, +} diff --git a/src/config/file_system.rs b/src/config/file_system.rs index 396b854..fd3a8d8 100644 --- a/src/config/file_system.rs +++ b/src/config/file_system.rs @@ -19,17 +19,34 @@ use std::{fs::read_to_string, path::PathBuf}; use anyhow::{Context, Result}; use bytes::Bytes; -use toml::Table; macro_rules! get { - ($default:path, $config:expr, $get_fn:ident, $key_one:expr, $($keys:expr),*) => { - try_get!{@default $default, $config, $get_fn, $key_one, $($keys),*} - .with_context(|| format!("Failed to parse '{}' as a '{}'", stringify!($key_one), stringify!($get_fn)))? + ($default:path, $config:expr, $key_one:ident, $($keys:ident),*) => { + { + let maybe_value = get!{@option $config, $key_one, $($keys),*}; + if let Some(value) = maybe_value { + value + } else { + $default().to_owned() + } + } + }; + + (@option $config:expr, $key_one:ident, $($keys:ident),*) => { + if let Some(key) = $config.$key_one.clone() { + get!{@option key, $($keys),*} + } else { + None + } + }; + (@option $config:expr, $key_one:ident) => { + $config.$key_one }; - (@path_if_none $config:expr, $option_default:expr, $default:path, $key_one:expr, $($keys:expr),*) => { + + (@path_if_none $config:expr, $option_default:expr, $default:path, $key_one:ident, $($keys:ident),*) => { { - let maybe_download_dir = - try_get! {@option $config, as_str, $key_one, $($keys),*}; + let maybe_download_dir: Option<PathBuf> = + get! {@option $config, $key_one, $($keys),*}; let down_dir = if let Some(dir) = maybe_download_dir { PathBuf::from(dir) @@ -44,35 +61,10 @@ macro_rules! get { create_path(down_dir)? } }; - (@path $config:expr, $default:path, $key_one:expr, $($keys:expr),*) => { + (@path $config:expr, $default:path, $key_one:ident, $($keys:ident),*) => { get! {@path_if_none $config, None, $default, $key_one, $($keys),*} }; } -macro_rules! try_get { - (@option $config:expr, $get_fn:ident, $key_one:expr, $($keys:expr),*) => { - $config.get($key_one).map(|val| { - try_get! {@option val, $get_fn, $($keys),*} - }).flatten().flatten() - }; - (@option $config:expr, $get_fn:ident, $key_one:expr) => { - $config.get($key_one).map(|val| val.$get_fn()) - }; - - (@default $default:path, $config:expr, $get_fn:ident, $key_one:expr, $($keys:expr),*) => { - if let Some(a) = $config.get($key_one) { - try_get! {@default $default, a, $get_fn, $($keys),*} - } else { - Some($default()) - } - }; - (@default $default:path, $config:expr, $get_fn:ident, $key_one:expr) => { - if let Some(a) = $config.get($key_one) { - a.$get_fn() - } else { - Some($default()) - } - }; -} impl Config { pub fn from_config_file( @@ -83,39 +75,36 @@ impl Config { .map(|val| Ok(val)) .unwrap_or_else(|| -> Result<_> { paths::config_path() })?; - let config: Table = read_to_string(config_file_path).unwrap_or("".to_owned()) - .parse() - .context("Failed to parse the config file as toml")?; + let config: super::definitions::ConfigFile = + toml::from_str(&read_to_string(config_file_path).unwrap_or("".to_owned())) + .context("Failed to parse the config file as toml")?; Ok(Self { select: SelectConfig { - playback_speed: get! {select::playback_speed, config, as_float, "select", "playback_speed"}, - subtitle_langs: - get! {select::subtitle_langs, config, as_str, "select", "subtitle_langs"} - .to_owned(), + playback_speed: get! {select::playback_speed, config, select, playback_speed}, + subtitle_langs: get! {select::subtitle_langs, config, select, subtitle_langs}, }, watch: WatchConfig { - local_comments_length: get! {watch::local_comments_length, config, as_integer, "watch", "local_comments_length"} - as usize, + local_comments_length: get! {watch::local_comments_length, config, watch, local_comments_length}, }, update: UpdateConfig { - max_backlog: get! {update::max_backlog, config, as_integer, "update", "max_backlog"} - as u32, + max_backlog: get! {update::max_backlog, config, update, max_backlog}, }, paths: PathsConfig { - download_dir: get! {@path config, paths::download_dir, "paths", "download_dir"}, - mpv_config_path: get! {@path config, paths::mpv_config_path, "paths", "mpv_config_path"}, - mpv_input_path: get! {@path config, paths::mpv_input_path, "paths", "mpv_input_path"}, - database_path: get! {@path_if_none config, db_path, paths::database_path, "paths", "database_path"}, - last_selection_path: get! {@path config, paths::last_selection_path, "paths", "last_selection_path"}, + download_dir: get! {@path config, paths::download_dir, paths, download_dir}, + mpv_config_path: get! {@path config, paths::mpv_config_path, paths, mpv_config_path}, + mpv_input_path: get! {@path config, paths::mpv_input_path, paths, mpv_input_path}, + database_path: get! {@path_if_none config, db_path, paths::database_path, paths, database_path}, + last_selection_path: get! {@path config, paths::last_selection_path, paths, last_selection_path}, }, download: DownloadConfig { max_cache_size: { - let bytes_str = get! {download::max_cache_size, config, as_str, "download", "max_cache_path"}; + let bytes_str: String = + get! {download::max_cache_size, config, download, max_cache_size}; let number: Bytes = bytes_str .parse() .context("Failed to parse max_cache_size")?; - number.as_u64() + number }, }, }) diff --git a/src/config/mod.rs b/src/config/mod.rs index 26d27eb..3d0d0b5 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -10,7 +10,10 @@ use std::path::PathBuf; +use bytes::Bytes; + mod default; +mod definitions; pub mod file_system; pub struct Config { @@ -24,7 +27,7 @@ pub struct UpdateConfig { pub max_backlog: u32, } pub struct DownloadConfig { - pub max_cache_size: u64, + pub max_cache_size: Bytes, } pub struct SelectConfig { pub playback_speed: f64, |