diff options
author | sushi-shi <47691267+sushi-shi@users.noreply.github.com> | 2024-02-13 22:00:19 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-13 17:00:19 -0500 |
commit | 96418c064ef617f62618a1baee518a823915955b (patch) | |
tree | b1c3eafc17ab784668c45f896d7672b4e21e31ea | |
parent | 203bd8977b56218d3972de007d403a3fdf9d95f7 (diff) |
Add command for printing embedded configs (#487)
* Add command for printing embedded configs
* Typo
* Use doccomments instead of procmacro
* Typo
-rw-r--r-- | config/joshuto.toml | 2 | ||||
-rw-r--r-- | config/theme.toml | 2 | ||||
-rw-r--r-- | src/commands/bookmark.rs | 13 | ||||
-rw-r--r-- | src/config/clean/app/config.rs | 9 | ||||
-rw-r--r-- | src/config/clean/app/mod.rs | 4 | ||||
-rw-r--r-- | src/config/clean/bookmarks.rs | 10 | ||||
-rw-r--r-- | src/config/clean/icon/config.rs | 8 | ||||
-rw-r--r-- | src/config/clean/icon/mod.rs | 5 | ||||
-rw-r--r-- | src/config/clean/keymap/config.rs | 8 | ||||
-rw-r--r-- | src/config/clean/keymap/mod.rs | 4 | ||||
-rw-r--r-- | src/config/clean/mimetype/config.rs | 10 | ||||
-rw-r--r-- | src/config/clean/preview/config.rs | 8 | ||||
-rw-r--r-- | src/config/clean/theme/config.rs | 8 | ||||
-rw-r--r-- | src/config/clean/theme/mod.rs | 4 | ||||
-rw-r--r-- | src/config/config_type.rs | 75 | ||||
-rw-r--r-- | src/config/mod.rs | 33 | ||||
-rw-r--r-- | src/error/error_type.rs | 10 | ||||
-rw-r--r-- | src/main.rs | 55 |
18 files changed, 185 insertions, 83 deletions
diff --git a/config/joshuto.toml b/config/joshuto.toml index b7d4626..4ab9cbc 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -23,7 +23,7 @@ show_icons = true # none, absolute, relative line_number_style = "none" -# size, mtime, user, gourp, perm. can be combined with |. +# size, mtime, user, gourp, perm. can be combined with |. # `none` to disable, `all` to enable all # all and none can't be combined with other options linemode = "size" diff --git a/config/theme.toml b/config/theme.toml index fce3633..5d11e39 100644 --- a/config/theme.toml +++ b/config/theme.toml @@ -85,7 +85,7 @@ bold = true ########################################## ## File list - Override style by extension ########################################## -# This sections allows to override the basic +# This sections allows to override the basic # style with a specific style for the file's # extension. diff --git a/src/commands/bookmark.rs b/src/commands/bookmark.rs index 2371c44..ce83d95 100644 --- a/src/commands/bookmark.rs +++ b/src/commands/bookmark.rs @@ -7,7 +7,7 @@ use ratatui::widgets::Clear; use termion::event::Event; use crate::config::raw::bookmarks::{BookmarkRaw, BookmarksRaw}; -use crate::config::search_directories; +use crate::config::{search_directories, ConfigType}; use crate::context::AppContext; use crate::error::AppResult; use crate::event::{process_event, AppEvent}; @@ -17,7 +17,7 @@ use crate::ui::widgets::TuiMenu; use crate::ui::AppBackend; use crate::util::unix; -use crate::{BOOKMARKS_FILE, BOOKMARKS_T, CONFIG_HIERARCHY}; +use crate::{BOOKMARKS_T, CONFIG_HIERARCHY}; use super::change_directory::change_directory; @@ -33,10 +33,11 @@ fn find_bookmark_file() -> Option<path::PathBuf> { pub fn add_bookmark(context: &mut AppContext, backend: &mut AppBackend) -> AppResult { let cwd = std::env::current_dir()?; - let bookmark_path = match search_directories(BOOKMARKS_FILE, &CONFIG_HIERARCHY) { - Some(file_path) => Some(file_path), - None => find_bookmark_file(), - }; + let bookmark_path = + match search_directories(ConfigType::Bookmarks.as_filename(), &CONFIG_HIERARCHY) { + Some(file_path) => Some(file_path), + None => find_bookmark_file(), + }; if let Some(bookmark_path) = bookmark_path { let key = poll_for_bookmark_key(context, backend); diff --git a/src/config/clean/app/config.rs b/src/config/clean/app/config.rs index 0995e8d..60b088d 100644 --- a/src/config/clean/app/config.rs +++ b/src/config/clean/app/config.rs @@ -2,9 +2,8 @@ use std::collections::HashMap; use crate::{ config::{ - parse_config_or_default, raw::app::{AppConfigRaw, CustomCommand}, - TomlConfigFile, + ConfigType, TomlConfigFile, }, error::AppResult, }; @@ -71,8 +70,10 @@ impl std::default::Default for AppConfig { } impl TomlConfigFile for AppConfig { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<AppConfigRaw, AppConfig>(file_name) + type Raw = AppConfigRaw; + + fn get_type() -> ConfigType { + ConfigType::App } } diff --git a/src/config/clean/app/mod.rs b/src/config/clean/app/mod.rs index 11fb46a..d517b31 100644 --- a/src/config/clean/app/mod.rs +++ b/src/config/clean/app/mod.rs @@ -7,7 +7,7 @@ pub mod tab; pub use config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/joshuto.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/joshuto.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\joshuto.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\joshuto.toml"); diff --git a/src/config/clean/bookmarks.rs b/src/config/clean/bookmarks.rs index 370fef2..155755d 100644 --- a/src/config/clean/bookmarks.rs +++ b/src/config/clean/bookmarks.rs @@ -3,16 +3,16 @@ use termion::event::Event; use std::collections::HashMap; use crate::config::raw::bookmarks::BookmarksRaw; -use crate::config::TomlConfigFile; +use crate::config::{ConfigType, TomlConfigFile}; use crate::util::keyparse; -use crate::config::parse_config_or_default; - pub type Bookmarks = HashMap<Event, String>; impl TomlConfigFile for Bookmarks { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<BookmarksRaw, Bookmarks>(file_name) + type Raw = BookmarksRaw; + + fn get_type() -> ConfigType { + ConfigType::Bookmarks } } diff --git a/src/config/clean/icon/config.rs b/src/config/clean/icon/config.rs index 02a80c3..a0c25af 100644 --- a/src/config/clean/icon/config.rs +++ b/src/config/clean/icon/config.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::{ - config::{parse_config_or_default, raw::icon::IconsRaw, TomlConfigFile}, + config::{raw::icon::IconsRaw, ConfigType, TomlConfigFile}, error::AppResult, }; @@ -30,8 +30,10 @@ impl std::default::Default for Icons { } impl TomlConfigFile for Icons { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<IconsRaw, Icons>(file_name) + type Raw = IconsRaw; + + fn get_type() -> ConfigType { + ConfigType::Icons } } diff --git a/src/config/clean/icon/mod.rs b/src/config/clean/icon/mod.rs index ac4a11a..e23656d 100644 --- a/src/config/clean/icon/mod.rs +++ b/src/config/clean/icon/mod.rs @@ -2,7 +2,8 @@ mod config; pub use config::*; -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/icons.toml"); +#[cfg(not(target_os = "windows"))] +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/icons.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\icons.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\icons.toml"); diff --git a/src/config/clean/keymap/config.rs b/src/config/clean/keymap/config.rs index 55e1bf9..c51721a 100644 --- a/src/config/clean/keymap/config.rs +++ b/src/config/clean/keymap/config.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use termion::event::Event; use crate::config::raw::keymap::{AppKeyMappingRaw, CommandKeymap}; -use crate::config::{parse_config_or_default, TomlConfigFile}; +use crate::config::{ConfigType, TomlConfigFile}; use crate::error::AppResult; use crate::key_command::{Command, CommandKeybind}; use crate::traits::ToString; @@ -113,8 +113,10 @@ impl From<AppKeyMappingRaw> for AppKeyMapping { } impl TomlConfigFile for AppKeyMapping { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<AppKeyMappingRaw, AppKeyMapping>(file_name) + type Raw = AppKeyMappingRaw; + + fn get_type() -> ConfigType { + ConfigType::Keymap } } diff --git a/src/config/clean/keymap/mod.rs b/src/config/clean/keymap/mod.rs index f68fbef..4398f8d 100644 --- a/src/config/clean/keymap/mod.rs +++ b/src/config/clean/keymap/mod.rs @@ -3,7 +3,7 @@ mod config; pub use self::config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/keymap.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/keymap.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\keymap.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\keymap.toml"); diff --git a/src/config/clean/mimetype/config.rs b/src/config/clean/mimetype/config.rs index 166e7e2..2419f88 100644 --- a/src/config/clean/mimetype/config.rs +++ b/src/config/clean/mimetype/config.rs @@ -1,8 +1,6 @@ use std::collections::HashMap; -use crate::config::{ - parse_config_or_default, raw::mimetype::AppProgramRegistryRaw, TomlConfigFile, -}; +use crate::config::{raw::mimetype::AppProgramRegistryRaw, ConfigType, TomlConfigFile}; use super::{ExtensionAppList, MimetypeAppList}; @@ -69,7 +67,9 @@ impl From<AppProgramRegistryRaw> for AppProgramRegistry { } impl TomlConfigFile for AppProgramRegistry { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<AppProgramRegistryRaw, AppProgramRegistry>(file_name) + type Raw = AppProgramRegistryRaw; + + fn get_type() -> ConfigType { + ConfigType::Mimetype } } diff --git a/src/config/clean/preview/config.rs b/src/config/clean/preview/config.rs index 0588c5f..1490cb3 100644 --- a/src/config/clean/preview/config.rs +++ b/src/config/clean/preview/config.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use serde::Deserialize; -use crate::config::{parse_config_or_default, raw::preview::FileEntryPreviewRaw, TomlConfigFile}; +use crate::config::{raw::preview::FileEntryPreviewRaw, ConfigType, TomlConfigFile}; #[derive(Debug, Deserialize)] pub struct FileEntryPreviewEntry { @@ -17,8 +17,10 @@ pub struct FileEntryPreview { } impl TomlConfigFile for FileEntryPreview { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<FileEntryPreviewRaw, FileEntryPreview>(file_name) + type Raw = FileEntryPreviewRaw; + + fn get_type() -> ConfigType { + ConfigType::Preview } } diff --git a/src/config/clean/theme/config.rs b/src/config/clean/theme/config.rs index 9028490..5be88fc 100644 --- a/src/config/clean/theme/config.rs +++ b/src/config/clean/theme/config.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::config::raw::theme::AppThemeRaw; -use crate::config::{parse_config_or_default, TomlConfigFile}; +use crate::config::{ConfigType, TomlConfigFile}; use crate::error::AppResult; use super::style::AppStyle; @@ -30,8 +30,10 @@ impl AppTheme { } impl TomlConfigFile for AppTheme { - fn get_config(file_name: &str) -> Self { - parse_config_or_default::<AppThemeRaw, AppTheme>(file_name) + type Raw = AppThemeRaw; + + fn get_type() -> ConfigType { + ConfigType::Theme } } diff --git a/src/config/clean/theme/mod.rs b/src/config/clean/theme/mod.rs index a9f7cbb..a6694c9 100644 --- a/src/config/clean/theme/mod.rs +++ b/src/config/clean/theme/mod.rs @@ -5,7 +5,7 @@ pub mod tab; pub use config::*; #[cfg(not(target_os = "windows"))] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/theme.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("../../../../config/theme.toml"); #[cfg(target_os = "windows")] -const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\theme.toml"); +pub const DEFAULT_CONFIG_FILE_PATH: &str = include_str!("..\\..\\..\\..\\config\\theme.toml"); diff --git a/src/config/config_type.rs b/src/config/config_type.rs new file mode 100644 index 0000000..7a4755a --- /dev/null +++ b/src/config/config_type.rs @@ -0,0 +1,75 @@ +#[derive(Copy, Clone, Debug)] +pub enum ConfigType { + App, + Mimetype, + Keymap, + Theme, + Preview, + Bookmarks, + Icons, +} + +impl std::fmt::Display for ConfigType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_str()) + } +} + +impl clap::ValueEnum for ConfigType { + fn value_variants<'a>() -> &'a [Self] { + Self::enumerate() + } + + fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> { + Some(clap::builder::PossibleValue::new(self.as_str())) + } +} + +impl ConfigType { + pub const fn enumerate() -> &'static [Self] { + &[ + Self::App, + Self::Mimetype, + Self::Keymap, + Self::Theme, + Self::Preview, + Self::Bookmarks, + Self::Icons, + ] + } + + pub const fn as_str(&self) -> &'static str { + match self { + Self::App => "joshuto", + Self::Mimetype => "mimetype", + Self::Keymap => "keymap", + Self::Theme => "theme", + Self::Preview => "preview", + Self::Bookmarks => "bookmarks", + Self::Icons => "icons", + } + } + + pub const fn as_filename(&self) -> &'static str { + match self { + Self::App => "joshuto.toml", + Self::Mimetype => "mimetype.toml", + Self::Keymap => "keymap.toml", + Self::Theme => "theme.toml", + Self::Preview => "preview.toml", + Self::Bookmarks => "bookmarks.toml", + Self::Icons => "icons.toml", + } + } + + pub const fn embedded_config(&self) -> Option<&'static str> { + use super::clean; + match self { + Self::App => Some(clean::app::DEFAULT_CONFIG_FILE_PATH), + Self::Keymap => Some(clean::keymap::DEFAULT_CONFIG_FILE_PATH), + Self::Theme => Some(clean::theme::DEFAULT_CONFIG_FILE_PATH), + Self::Icons => Some(clean::icon::DEFAULT_CONFIG_FILE_PATH), + Self::Mimetype | Self::Preview | Self::Bookmarks => None, + } + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 1f468ef..58d3f40 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,9 @@ pub mod clean; pub mod raw; +pub mod config_type; +pub use config_type::ConfigType; + use serde::de::DeserializeOwned; use std::fs; use std::path::{Path, PathBuf}; @@ -8,8 +11,14 @@ use std::path::{Path, PathBuf}; use crate::error::AppResult; use crate::CONFIG_HIERARCHY; -pub trait TomlConfigFile { - fn get_config(file_name: &str) -> Self; +pub trait TomlConfigFile: Sized + Default { + type Raw: Into<Self> + DeserializeOwned; + + fn get_type() -> config_type::ConfigType; + + fn get_config() -> Self { + parse_config_or_default::<Self::Raw, Self>(Self::get_type().as_filename()) + } } // searches a list of folders for a given file in order of preference @@ -17,13 +26,10 @@ pub fn search_directories<P>(file_name: &str, directories: &[P]) -> Option<PathB where P: AsRef<Path>, { - for path in directories.iter() { - let file_path = path.as_ref().join(file_name); - if file_path.exists() { - return Some(file_path); - } - } - None + directories + .iter() + .map(|path| path.as_ref().join(file_name)) + .find(|path| path.exists()) } pub fn search_config_directories(file_name: &str) -> Option<PathBuf> { @@ -32,18 +38,17 @@ pub fn search_config_directories(file_name: &str) -> Option<PathBuf> { fn parse_file_to_config<T, S>(file_path: &Path) -> AppResult<S> where - T: DeserializeOwned, - S: From<T>, + T: DeserializeOwned + Into<S>, { let file_contents = fs::read_to_string(file_path)?; let config = toml::from_str::<T>(&file_contents)?; - Ok(S::from(config)) + Ok(config.into()) } pub fn parse_config_or_default<T, S>(file_name: &str) -> S where - T: DeserializeOwned, - S: From<T> + std::default::Default, + T: DeserializeOwned + Into<S>, + S: std::default::Default, { match search_config_directories(file_name) { Some(file_path) => match parse_file_to_config::<T, S>(&file_path) { diff --git a/src/error/error_type.rs b/src/error/error_type.rs index 9eef287..4913d76 100644 --- a/src/error/error_type.rs +++ b/src/error/error_type.rs @@ -9,12 +9,20 @@ pub struct AppError { _cause: String, } -#[allow(dead_code)] impl AppError { pub fn new(_kind: AppErrorKind, _cause: String) -> Self { Self { _kind, _cause } } + pub fn error(cause: impl ToString) -> Self { + Self::new(AppErrorKind::UnknownError, cause.to_string()) + } + + pub fn fail<T>(cause: impl ToString) -> Result<T, AppError> { + Err(Self::error(cause)) + } + + #[allow(dead_code)] pub fn kind(&self) -> &AppErrorKind { &self._kind } diff --git a/src/main.rs b/src/main.rs index 04a2a93..7a5d44d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ use lazy_static::lazy_static; use config::clean::bookmarks::Bookmarks; use config::clean::mimetype::AppProgramRegistry; use config::clean::theme::AppTheme; -use config::TomlConfigFile; +use config::{ConfigType, TomlConfigFile}; use util::cwd; use crate::commands::quit::QuitAction; @@ -42,14 +42,6 @@ use crate::error::AppError; const PROGRAM_NAME: &str = "joshuto"; const CONFIG_HOME: &str = "JOSHUTO_CONFIG_HOME"; -const CONFIG_FILE: &str = "joshuto.toml"; -const MIMETYPE_FILE: &str = "mimetype.toml"; -const KEYMAP_FILE: &str = "keymap.toml"; -const THEME_FILE: &str = "theme.toml"; -const PREVIEW_FILE: &str = "preview.toml"; -const BOOKMARKS_FILE: &str = "bookmarks.toml"; -const ICONS_FILE: &str = "icons.toml"; - lazy_static! { // dynamically builds the config hierarchy static ref CONFIG_HIERARCHY: Vec<PathBuf> = { @@ -76,11 +68,11 @@ lazy_static! { config_dirs }; - static ref THEME_T: AppTheme = AppTheme::get_config(THEME_FILE); - static ref MIMETYPE_T: AppProgramRegistry = AppProgramRegistry::get_config(MIMETYPE_FILE); - static ref PREVIEW_T: FileEntryPreview = FileEntryPreview::get_config(PREVIEW_FILE); - static ref BOOKMARKS_T: Mutex<Bookmarks> = Mutex::new(Bookmarks::get_config(BOOKMARKS_FILE)); - static ref ICONS_T: Icons = Icons::get_config(ICONS_FILE); + static ref THEME_T: AppTheme = AppTheme::get_config(); + static ref MIMETYPE_T: AppProgramRegistry = AppProgramRegistry::get_config(); + static ref PREVIEW_T: FileEntryPreview = FileEntryPreview::get_config(); + static ref BOOKMARKS_T: Mutex<Bookmarks> = Mutex::new(Bookmarks::get_config()); + static ref ICONS_T: Icons = Icons::get_config(); static ref HOME_DIR: Option<PathBuf> = dirs_next::home_dir(); static ref USERNAME: String = whoami::username(); @@ -120,24 +112,38 @@ pub struct Args { #[derive(Clone, Debug, Subcommand)] pub enum Commands { - #[command(about = "Show shell completions")] + /// Print completions for a given shell. Completions { shell: clap_complete::Shell }, - #[command(about = "Show version")] + /// Print embedded toml configuration for a given config type. + Config { + /// Filename of the given config without '.toml' extension. + config_type: ConfigType, + }, + + /// Print 'joshuto' build version. Version, } fn run_main(args: Args) -> Result<i32, AppError> { if let Some(command) = args.commands { - match command { + let result = match command { Commands::Completions { shell } => { let mut app = Args::command(); let bin_name = app.get_name().to_string(); clap_complete::generate(shell, &mut app, bin_name, &mut std::io::stdout()); - return Ok(0); + Ok(0) } - Commands::Version => return print_version(), - } + Commands::Config { config_type } => match config_type.embedded_config() { + None => AppError::fail("no default config"), + Some(config) => { + println!("{config}"); + Ok(0) + } + }, + Commands::Version => print_version(), + }; + return result; } if args.version { @@ -145,15 +151,12 @@ fn run_main(args: Args) -> Result<i32, AppError> { } if let Some(path) = args.rest.first() { - if let Err(err) = cwd::set_current_dir(path) { - eprintln!("{err}"); - process::exit(1); - } + cwd::set_current_dir(path)?; } // make sure all configs have been loaded before starting - let config = AppConfig::get_config(CONFIG_FILE); - let keymap = AppKeyMapping::get_config(KEYMAP_FILE); + let config = AppConfig::get_config(); + let keymap = AppKeyMapping::get_config(); lazy_static::initialize(&THEME_T); lazy_static::initialize(&MIMETYPE_T); lazy_static::initialize(&PREVIEW_T); |