summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2021-05-16 10:55:24 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2021-05-16 10:55:24 -0400
commit2ab40a4911287c3ecdf56a70f3c716218e454d62 (patch)
tree44039d00ef98252e6f1d2a834cff22ced1b79785 /src
parent314245d36f3ca7da9ce329513938b452a2c90f1d (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.rs2
-rw-r--r--src/config/mimetype/entry.rs27
-rw-r--r--src/config/mimetype/mod.rs2
-rw-r--r--src/config/mimetype/registry.rs58
-rw-r--r--src/config/mod.rs23
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
- }
- }
-}