diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-05-16 10:55:24 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2021-05-16 10:55:24 -0400 |
commit | 2ab40a4911287c3ecdf56a70f3c716218e454d62 (patch) | |
tree | 44039d00ef98252e6f1d2a834cff22ced1b79785 /src | |
parent | 314245d36f3ca7da9ce329513938b452a2c90f1d (diff) |
rework mimetype config
- users can now specify variables/classes that different
extensions can "inherit" from, to prevent having to write the
same mimetype multiple times
```
[extension]
[extension.png]
inherit = "some_predefined_class"
app_list = [
{ command = "more_entries" } ]
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/open_file.rs | 2 | ||||
-rw-r--r-- | src/config/mimetype/entry.rs | 27 | ||||
-rw-r--r-- | src/config/mimetype/mod.rs | 2 | ||||
-rw-r--r-- | src/config/mimetype/registry.rs | 58 | ||||
-rw-r--r-- | src/config/mod.rs | 23 |
5 files changed, 72 insertions, 40 deletions
diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs index a9ca307..f82ea55 100644 --- a/src/commands/open_file.rs +++ b/src/commands/open_file.rs @@ -16,7 +16,7 @@ pub fn get_options<'a>(path: &path::Path) -> Vec<&'a AppMimetypeEntry> { let mut options: Vec<&AppMimetypeEntry> = Vec::new(); if let Some(file_ext) = path.extension() { if let Some(file_ext) = file_ext.to_str() { - let ext_entries = MIMETYPE_T.get_entries_for_ext(file_ext); + let ext_entries = MIMETYPE_T.app_list_for_ext(file_ext); options.extend(ext_entries); } } diff --git a/src/config/mimetype/entry.rs b/src/config/mimetype/entry.rs index bfebf07..ee6e09d 100644 --- a/src/config/mimetype/entry.rs +++ b/src/config/mimetype/entry.rs @@ -3,7 +3,32 @@ use std::fmt; use std::io::Read; use std::process; -#[derive(Debug, Deserialize)] +#[derive(Clone, Debug, Deserialize)] +pub struct AppList { + #[serde(default, rename = "inherit")] + _inherit: String, + #[serde(default, rename = "app_list")] + _app_list: Vec<AppMimetypeEntry>, +} + +impl AppList { + pub fn new(_inherit: String, _app_list: Vec<AppMimetypeEntry>) -> Self { + Self { + _inherit, + _app_list, + } + } + + pub fn parent(&self) -> &str { + self._inherit.as_str() + } + + pub fn app_list(&self) -> &[AppMimetypeEntry] { + &self._app_list.as_slice() + } +} + +#[derive(Clone, Debug, Deserialize)] pub struct AppMimetypeEntry { #[serde(rename = "command")] _command: String, diff --git a/src/config/mimetype/mod.rs b/src/config/mimetype/mod.rs index a8cae63..3ab8beb 100644 --- a/src/config/mimetype/mod.rs +++ b/src/config/mimetype/mod.rs @@ -1,5 +1,5 @@ mod entry; mod registry; -pub use self::entry::AppMimetypeEntry; +pub use self::entry::{AppList, AppMimetypeEntry}; pub use self::registry::AppMimetypeRegistry; diff --git a/src/config/mimetype/registry.rs b/src/config/mimetype/registry.rs index 3daf956..b2f44d3 100644 --- a/src/config/mimetype/registry.rs +++ b/src/config/mimetype/registry.rs @@ -1,39 +1,69 @@ use serde_derive::Deserialize; use std::collections::HashMap; -use super::AppMimetypeEntry; -use crate::config::{parse_config_file, ConfigStructure}; +use super::{AppList, AppMimetypeEntry}; +use crate::config::{parse_to_config_file, ConfigStructure, Flattenable}; -pub type MimetypeRegistry = HashMap<String, Vec<AppMimetypeEntry>>; +pub type MimetypeRegistry = HashMap<String, AppList>; #[derive(Debug, Deserialize)] +pub struct RawAppMimetypeRegistry { + #[serde(default, rename = "class")] + pub _class: HashMap<String, Vec<AppMimetypeEntry>>, + #[serde(default, rename = "extension")] + pub _extension: MimetypeRegistry, +} + +impl Flattenable<AppMimetypeRegistry> for RawAppMimetypeRegistry { + fn flatten(self) -> AppMimetypeRegistry { + let mut registry = MimetypeRegistry::new(); + + for (ext, app_list) in self._extension { + let class = app_list.parent(); + let mut combined_app_list: Vec<AppMimetypeEntry> = self + ._class + .get(class) + .map(|v| (*v).clone()) + .unwrap_or(vec![]); + combined_app_list.extend_from_slice(app_list.app_list()); + let combined_app_list = AppList::new(class.to_string(), combined_app_list); + registry.insert(ext, combined_app_list); + } + + AppMimetypeRegistry { + _extension: registry, + } + } +} + +#[derive(Debug)] pub struct AppMimetypeRegistry { - #[serde(default, skip)] - empty_vec: Vec<AppMimetypeEntry>, - #[serde(default)] - pub extension: MimetypeRegistry, + // pub _class: HashMap<String, Vec<AppMimetypeEntry>>, + pub _extension: MimetypeRegistry, } +pub const EMPTY_ARR: [AppMimetypeEntry; 0] = []; + impl AppMimetypeRegistry { - pub fn get_entries_for_ext(&self, extension: &str) -> &[AppMimetypeEntry] { - match self.extension.get(extension) { - Some(s) => s, - None => &self.empty_vec, + pub fn app_list_for_ext(&self, extension: &str) -> &[AppMimetypeEntry] { + match self._extension.get(extension) { + Some(s) => s.app_list(), + None => &EMPTY_ARR, } } } impl ConfigStructure for AppMimetypeRegistry { fn get_config(file_name: &str) -> Self { - parse_config_file::<AppMimetypeRegistry>(file_name).unwrap_or_else(Self::default) + parse_to_config_file::<RawAppMimetypeRegistry, AppMimetypeRegistry>(file_name) + .unwrap_or_else(Self::default) } } impl std::default::Default for AppMimetypeRegistry { fn default() -> Self { Self { - empty_vec: Vec::new(), - extension: MimetypeRegistry::new(), + _extension: MimetypeRegistry::new(), } } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 169e0ed..6cc4386 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -61,26 +61,3 @@ where }; Some(config.flatten()) } - -// parses a config file into its appropriate format -fn parse_config_file<T>(filename: &str) -> Option<T> -where - T: DeserializeOwned, -{ - let file_path = search_directories(filename, &CONFIG_HIERARCHY)?; - let file_contents = match fs::read_to_string(&file_path) { - Ok(content) => content, - Err(e) => { - eprintln!("Error reading {} file: {}", filename, e); - return None; - } - }; - - match toml::from_str::<T>(&file_contents) { - Ok(config) => Some(config), - Err(e) => { - eprintln!("Error parsing {} file: {}", filename, e); - None - } - } -} |