summaryrefslogtreecommitdiffstats
path: root/src/commands/open_file.rs
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2020-09-19 21:21:33 -0400
committerJiayi Zhao <jeff.no.zhao@gmail.com>2020-09-19 21:21:33 -0400
commit7b4c611ed4d804bd52aeda0a619a54bea9b1e13d (patch)
tree7ba31fff7d5de171aadfc32c67f81dd64428b3ba /src/commands/open_file.rs
parent7741d4d2c8798ad0bb609e97fb3bda86c5318a36 (diff)
Change command to use an enum instead of polymorphism
Diffstat (limited to 'src/commands/open_file.rs')
-rw-r--r--src/commands/open_file.rs281
1 files changed, 108 insertions, 173 deletions
diff --git a/src/commands/open_file.rs b/src/commands/open_file.rs
index 7299b74..7ce3c62 100644
--- a/src/commands/open_file.rs
+++ b/src/commands/open_file.rs
@@ -1,6 +1,5 @@
use std::path;
-use crate::commands::{ChangeDirectory, JoshutoCommand, JoshutoRunnable};
use crate::config::mimetype::JoshutoMimetypeEntry;
use crate::context::JoshutoContext;
use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult};
@@ -8,206 +7,142 @@ use crate::ui::widgets::TuiTextField;
use crate::ui::TuiBackend;
use crate::util::load_child::LoadChild;
-use crate::MIMETYPE_T;
-
-#[derive(Clone, Debug)]
-pub struct OpenFile;
+use super::change_directory;
-impl OpenFile {
- pub fn new() -> Self {
- OpenFile
- }
- pub const fn command() -> &'static str {
- "open_file"
- }
+use crate::MIMETYPE_T;
- pub fn get_options<'a>(path: &path::Path) -> Vec<&'a JoshutoMimetypeEntry> {
- let mut options: Vec<&JoshutoMimetypeEntry> = 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);
- options.extend(ext_entries);
- }
+pub fn get_options<'a>(path: &path::Path) -> Vec<&'a JoshutoMimetypeEntry> {
+ let mut options: Vec<&JoshutoMimetypeEntry> = 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);
+ options.extend(ext_entries);
}
- options
}
- /*
- pub fn get_options<'a>(entry: &JoshutoDirEntry) -> Vec<&'a JoshutoMimetypeEntry> {
- let mut mimetype_options: Vec<&JoshutoMimetypeEntry> = Vec::new();
+ options
+}
- if let Some(file_ext) = entry.file_path().extension() {
- if let Some(file_ext) = file_ext.to_str() {
- let ext_entries = MIMETYPE_T.get_entries_for_ext(file_ext);
- mimetype_options.extend(ext_entries);
- }
+pub fn open(context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
+ if let Some(entry) = context
+ .tab_context_ref()
+ .curr_tab_ref()
+ .curr_list_ref()
+ .and_then(|s| s.curr_entry_ref())
+ {
+ if entry.file_path().is_dir() {
+ let path = entry.file_path().to_path_buf();
+ change_directory::cd(path.as_path(), context)?;
+ LoadChild::load_child(context)?;
+ } else {
+ let paths: Vec<path::PathBuf> =
+ match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
+ Some(a) => a.get_selected_paths(),
+ None => vec![],
+ };
+ if paths.is_empty() {
+ return Err(JoshutoError::new(
+ JoshutoErrorKind::IONotFound,
+ String::from("No files selected"),
+ ));
}
- #[cfg(feature = "file_mimetype")]
- {
- if let Some(mimetype) = entry.metadata.mimetype.as_ref() {
- let mime_entries = MIMETYPE_T.get_entries_for_mimetype(mimetype.as_str());
- mimetype_options.extend(mime_entries);
+ let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect();
+ let options = get_options(paths[0].as_path());
+
+ if !options.is_empty() {
+ if options[0].get_fork() {
+ options[0].execute_with(files.as_slice())?;
+ } else {
+ backend.terminal_drop();
+ let res = options[0].execute_with(files.as_slice());
+ backend.terminal_restore()?;
+ res?;
}
+ } else {
+ open_with_helper(context, backend, options, files)?;
}
- mimetype_options
}
- */
-}
-
-impl JoshutoCommand for OpenFile {}
-
-impl std::fmt::Display for OpenFile {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- f.write_str(Self::command())
}
+ Ok(())
}
-impl JoshutoRunnable for OpenFile {
- fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
- if let Some(entry) = context
- .tab_context_ref()
- .curr_tab_ref()
- .curr_list_ref()
- .and_then(|s| s.get_curr_ref())
- {
- if entry.file_path().is_dir() {
- let path = entry.file_path().to_path_buf();
- ChangeDirectory::cd(path.as_path(), context)?;
- LoadChild::load_child(context)?;
- } else {
- let paths: Vec<path::PathBuf> =
- match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
- Some(a) => a.get_selected_paths(),
- None => vec![],
- };
- if paths.is_empty() {
- return Err(JoshutoError::new(
- JoshutoErrorKind::IONotFound,
- String::from("No files selected"),
- ));
- }
- let files: Vec<&std::ffi::OsStr> =
- paths.iter().filter_map(|e| e.file_name()).collect();
- let options = Self::get_options(paths[0].as_path());
-
- if !options.is_empty() {
- if options[0].get_fork() {
- options[0].execute_with(files.as_slice())?;
+pub fn open_with_helper<S>(
+ context: &mut JoshutoContext,
+ backend: &mut TuiBackend,
+ options: Vec<&JoshutoMimetypeEntry>,
+ files: Vec<S>,
+) -> std::io::Result<()>
+where
+ S: AsRef<std::ffi::OsStr>,
+{
+ const PROMPT: &str = "open_with ";
+
+ let user_input: Option<String> = {
+ let menu_options: Vec<String> = options
+ .iter()
+ .enumerate()
+ .map(|(i, e)| format!(" {} | {}", i, e))
+ .collect();
+
+ TuiTextField::default()
+ .prompt(":")
+ .prefix(PROMPT)
+ .menu_items(menu_options.iter().map(|s| s.as_str()))
+ .get_input(backend, context)
+ };
+ match user_input.as_ref() {
+ Some(user_input) if user_input.starts_with(PROMPT) => {
+ let user_input = &user_input[PROMPT.len()..];
+
+ match user_input.parse::<usize>() {
+ Ok(n) if n >= options.len() => Err(std::io::Error::new(
+ std::io::ErrorKind::InvalidData,
+ "option does not exist".to_string(),
+ )),
+ Ok(n) => {
+ let mimetype_entry = &options[n];
+ if mimetype_entry.get_fork() {
+ mimetype_entry.execute_with(files.as_slice())
} else {
backend.terminal_drop();
- let res = options[0].execute_with(files.as_slice());
+ let res = mimetype_entry.execute_with(files.as_slice());
backend.terminal_restore()?;
- res?;
+ res
}
- } else {
- OpenFileWith::open_with(context, backend, options, files)?;
}
- }
- }
- Ok(())
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct OpenFileWith;
-
-impl OpenFileWith {
- pub fn new() -> Self {
- OpenFileWith
- }
- pub const fn command() -> &'static str {
- "open_file_with"
- }
-
- pub fn open_with<S>(
- context: &mut JoshutoContext,
- backend: &mut TuiBackend,
- options: Vec<&JoshutoMimetypeEntry>,
- files: Vec<S>,
- ) -> std::io::Result<()>
- where
- S: AsRef<std::ffi::OsStr>,
- {
- const PROMPT: &str = "open_with ";
-
- let user_input: Option<String> = {
- let menu_options: Vec<String> = options
- .iter()
- .enumerate()
- .map(|(i, e)| format!(" {} | {}", i, e))
- .collect();
-
- TuiTextField::default()
- .prompt(":")
- .prefix(PROMPT)
- .menu_items(menu_options.iter().map(|s| s.as_str()))
- .get_input(backend, context)
- };
- match user_input.as_ref() {
- Some(user_input) if user_input.starts_with(PROMPT) => {
- let user_input = &user_input[PROMPT.len()..];
-
- match user_input.parse::<usize>() {
- Ok(n) if n >= options.len() => Err(std::io::Error::new(
- std::io::ErrorKind::InvalidData,
- "option does not exist".to_string(),
- )),
- Ok(n) => {
- let mimetype_entry = &options[n];
- if mimetype_entry.get_fork() {
- mimetype_entry.execute_with(files.as_slice())
- } else {
+ Err(_) => {
+ let mut args_iter = user_input.split_whitespace();
+ match args_iter.next() {
+ Some(cmd) => {
backend.terminal_drop();
- let res = mimetype_entry.execute_with(files.as_slice());
+ let res = JoshutoMimetypeEntry::new(String::from(cmd))
+ .args(args_iter)
+ .execute_with(files.as_slice());
backend.terminal_restore()?;
res
}
- }
- Err(_) => {
- let mut args_iter = user_input.split_whitespace();
- match args_iter.next() {
- Some(cmd) => {
- backend.terminal_drop();
- let res = JoshutoMimetypeEntry::new(String::from(cmd))
- .args(args_iter)
- .execute_with(files.as_slice());
- backend.terminal_restore()?;
- res
- }
- None => Ok(()),
- }
+ None => Ok(()),
}
}
}
- _ => Ok(()),
}
+ _ => Ok(()),
}
}
-impl JoshutoCommand for OpenFileWith {}
-
-impl std::fmt::Display for OpenFileWith {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- f.write_str(Self::command())
+pub fn open_with(context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
+ let paths: Vec<path::PathBuf> = match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
+ Some(a) => a.get_selected_paths(),
+ None => vec![],
+ };
+ if paths.is_empty() {
+ return Err(JoshutoError::new(
+ JoshutoErrorKind::IONotFound,
+ String::from("No files selected"),
+ ));
}
-}
-
-impl JoshutoRunnable for OpenFileWith {
- fn execute(&self, context: &mut JoshutoContext, backend: &mut TuiBackend) -> JoshutoResult<()> {
- let paths: Vec<path::PathBuf> =
- match context.tab_context_ref().curr_tab_ref().curr_list_ref() {
- Some(a) => a.get_selected_paths(),
- None => vec![],
- };
- if paths.is_empty() {
- return Err(JoshutoError::new(
- JoshutoErrorKind::IONotFound,
- String::from("No files selected"),
- ));
- }
- let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect();
- let options = OpenFile::get_options(paths[0].as_path());
+ let files: Vec<&std::ffi::OsStr> = paths.iter().filter_map(|e| e.file_name()).collect();
+ let options = get_options(paths[0].as_path());
- Self::open_with(context, backend, options, files)?;
- Ok(())
- }
+ open_with_helper(context, backend, options, files)?;
+ Ok(())
}