summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2022-10-23 16:10:46 +0200
committerqkzk <qu3nt1n@gmail.com>2022-10-23 16:10:46 +0200
commit0cc724be377761cb56426e79d03e10da48777d98 (patch)
treeea9081aa28359268812f85f4a1a6263e9e486670 /src
parentbcaf2be20ba101dd683db2446963222f94e8191f (diff)
result in completion, marks, display, actioner, eventchar
Diffstat (limited to 'src')
-rw-r--r--src/actioner.rs220
-rw-r--r--src/completion.rs35
-rw-r--r--src/display.rs20
-rw-r--r--src/event_char.rs120
-rw-r--r--src/fileinfo.rs22
-rw-r--r--src/main.rs4
-rw-r--r--src/marks.rs28
-rw-r--r--src/status.rs9
-rw-r--r--src/tab.rs8
9 files changed, 258 insertions, 208 deletions
diff --git a/src/actioner.rs b/src/actioner.rs
index 06cba50..5e4877a 100644
--- a/src/actioner.rs
+++ b/src/actioner.rs
@@ -60,79 +60,25 @@ impl Actioner {
/// Reaction to received events.
pub fn read_event(&self, tabs: &mut Status, ev: Event) -> FmResult<()> {
match ev {
- Event::Key(Key::ESC) => {
- self.escape(tabs);
- Ok(())
- }
- Event::Key(Key::Up) => {
- self.up(tabs);
- Ok(())
- }
- Event::Key(Key::Down) => {
- self.down(tabs);
- Ok(())
- }
- Event::Key(Key::Left) => {
- self.left(tabs);
- Ok(())
- }
- Event::Key(Key::Right) => {
- self.right(tabs);
- Ok(())
- }
- Event::Key(Key::Backspace) => {
- self.backspace(tabs);
- Ok(())
- }
- Event::Key(Key::Ctrl('d')) => {
- self.delete(tabs);
- Ok(())
- }
- Event::Key(Key::Ctrl('q')) => {
- self.escape(tabs);
- Ok(())
- }
- Event::Key(Key::Delete) => {
- self.delete(tabs);
- Ok(())
- }
- Event::Key(Key::Insert) => {
- (self.insert(tabs));
- Ok(())
- }
- Event::Key(Key::Char(c)) => {
- self.char(tabs, c);
- Ok(())
- }
- Event::Key(Key::Home) => {
- self.home(tabs);
- Ok(())
- }
- Event::Key(Key::End) => {
- (self.end(tabs));
- Ok(())
- }
- Event::Key(Key::PageDown) => {
- self.page_down(tabs);
- Ok(())
- }
- Event::Key(Key::PageUp) => {
- self.page_up(tabs);
- Ok(())
- }
+ Event::Key(Key::ESC) => self.escape(tabs),
+ Event::Key(Key::Up) => self.up(tabs),
+ Event::Key(Key::Down) => self.down(tabs),
+ Event::Key(Key::Left) => self.left(tabs),
+ Event::Key(Key::Right) => self.right(tabs),
+ Event::Key(Key::Backspace) => self.backspace(tabs),
+ Event::Key(Key::Ctrl('d')) => self.delete(tabs),
+ Event::Key(Key::Ctrl('q')) => self.escape(tabs),
+ Event::Key(Key::Delete) => self.delete(tabs),
+ Event::Key(Key::Insert) => self.insert(tabs),
+ Event::Key(Key::Char(c)) => self.char(tabs, c),
+ Event::Key(Key::Home) => self.home(tabs),
+ Event::Key(Key::End) => self.end(tabs),
+ Event::Key(Key::PageDown) => self.page_down(tabs),
+ Event::Key(Key::PageUp) => self.page_up(tabs),
Event::Key(Key::Enter) => self.enter(tabs),
- Event::Key(Key::Tab) => {
- self.tab(tabs);
- Ok(())
- }
- Event::Key(Key::WheelUp(_, _, _)) => {
- self.up(tabs);
- Ok(())
- }
- Event::Key(Key::WheelDown(_, _, _)) => {
- self.down(tabs);
- Ok(())
- }
+ Event::Key(Key::Tab) => self.tab(tabs),
+ Event::Key(Key::WheelUp(_, _, _)) => self.up(tabs),
+ Event::Key(Key::WheelDown(_, _, _)) => self.down(tabs),
Event::Key(Key::SingleClick(MouseButton::Left, row, _)) => {
self.left_click(tabs, row);
Ok(())
@@ -147,12 +93,12 @@ impl Actioner {
}
/// Leaving a mode reset the window
- fn escape(&self, tabs: &mut Status) {
- tabs.selected().event_normal().unwrap_or_default();
+ fn escape(&self, tabs: &mut Status) -> FmResult<()> {
+ tabs.selected().event_normal()
}
/// Move one line up
- fn up(&self, tabs: &mut Status) {
+ fn up(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_up_one_row(),
Mode::Jump => tabs.event_jumplist_prev(),
@@ -162,11 +108,12 @@ impl Actioner {
tabs.selected().completion.prev();
}
_ => (),
- }
+ };
+ Ok(())
}
/// Move one line down
- fn down(&self, tabs: &mut Status) {
+ fn down(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_down_one_row(),
Mode::Jump => tabs.event_jumplist_next(),
@@ -176,41 +123,49 @@ impl Actioner {
tabs.selected().completion.next();
}
_ => (),
- }
+ };
+ Ok(())
}
/// Move left in a string, move to parent in normal mode
- fn left(&self, tabs: &mut Status) {
+ fn left(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
- Mode::Normal => tabs.selected().event_move_to_parent().unwrap_or_default(),
+ Mode::Normal => tabs.selected().event_move_to_parent(),
Mode::Rename
| Mode::Chmod
| Mode::Newdir
| Mode::Newfile
| Mode::Exec
| Mode::Search
- | Mode::Goto => tabs.selected().event_move_cursor_left(),
- _ => (),
+ | Mode::Goto => {
+ tabs.selected().event_move_cursor_left();
+ Ok(())
+ }
+
+ _ => Ok(()),
}
}
/// Move right in a string, move to children in normal mode.
- fn right(&self, tabs: &mut Status) {
+ fn right(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
- Mode::Normal => tabs.selected().event_go_to_child().unwrap_or_default(),
+ Mode::Normal => tabs.selected().event_go_to_child(),
Mode::Rename
| Mode::Chmod
| Mode::Newdir
| Mode::Newfile
| Mode::Exec
| Mode::Search
- | Mode::Goto => tabs.selected().event_move_cursor_right(),
- _ => (),
+ | Mode::Goto => {
+ tabs.selected().event_move_cursor_right();
+ Ok(())
+ }
+ _ => Ok(()),
}
}
/// Deletes a char in input string
- fn backspace(&self, tabs: &mut Status) {
+ fn backspace(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Rename
| Mode::Newdir
@@ -218,15 +173,18 @@ impl Actioner {
| Mode::Newfile
| Mode::Exec
| Mode::Search
- | Mode::Goto => tabs.selected().event_delete_char_left(),
- Mode::Normal => (),
- _ => (),
+ | Mode::Goto => {
+ tabs.selected().event_delete_char_left();
+ Ok(())
+ }
+ Mode::Normal => Ok(()),
+ _ => Ok(()),
}
}
/// Deletes chars right of cursor in input string.
/// Remove current tab in normal mode.
- fn delete(&self, tabs: &mut Status) {
+ fn delete(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Rename
| Mode::Newdir
@@ -234,53 +192,65 @@ impl Actioner {
| Mode::Newfile
| Mode::Exec
| Mode::Search
- | Mode::Goto => tabs.selected().event_delete_chars_right(),
- Mode::Normal => tabs.drop_tab(),
- _ => (),
+ | Mode::Goto => {
+ tabs.selected().event_delete_chars_right();
+ Ok(())
+ }
+
+ Mode::Normal => {
+ tabs.drop_tab();
+ Ok(())
+ }
+ _ => Ok(()),
}
}
/// Insert a new tab in normal mode
- fn insert(&self, tabs: &mut Status) {
+ fn insert(&self, tabs: &mut Status) -> FmResult<()> {
if let Mode::Normal = tabs.selected().mode {
tabs.new_tab()
- }
+ };
+ Ok(())
}
/// Move to top or beggining of line.
- fn home(&self, tabs: &mut Status) {
+ fn home(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_go_top(),
_ => tabs.selected().event_cursor_home(),
- }
+ };
+ Ok(())
}
/// Move to end or end of line.
- fn end(&self, tabs: &mut Status) {
+ fn end(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_go_bottom(),
_ => tabs.selected().event_cursor_end(),
- }
+ };
+ Ok(())
}
/// Move down 10 rows
- fn page_down(&self, tabs: &mut Status) {
+ fn page_down(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_page_down(),
_ => (),
- }
+ };
+ Ok(())
}
/// Move up 10 rows
- fn page_up(&self, tabs: &mut Status) {
+ fn page_up(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Normal | Mode::Preview | Mode::Help => tabs.selected().event_page_up(),
_ => (),
- }
+ };
+ Ok(())
}
/// Execute a command
- fn enter(&self, tabs: &mut Status) -> Result<(), FmError> {
+ fn enter(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Rename => tabs.selected().exec_rename()?,
Mode::Newfile => tabs.selected().exec_newfile()?,
@@ -321,14 +291,15 @@ impl Actioner {
}
/// Select next completion and insert it
- fn tab(&self, tabs: &mut Status) {
+ fn tab(&self, tabs: &mut Status) -> FmResult<()> {
match tabs.selected().mode {
Mode::Goto | Mode::Exec | Mode::Search => {
tabs.selected().event_replace_input_with_completion()
}
Mode::Normal => tabs.next(),
_ => (),
- }
+ };
+ Ok(())
}
fn ctrl_f(&self, tabs: &mut Status) -> FmResult<()> {
@@ -344,32 +315,35 @@ impl Actioner {
/// Match read key to a relevent event, depending on keybindings.
/// Keybindings are read from `Config`.
- fn char(&self, tabs: &mut Status, c: char) {
- match tabs.selected().mode {
+ fn char(&self, status: &mut Status, c: char) -> FmResult<()> {
+ match status.selected().mode {
Mode::Newfile | Mode::Newdir | Mode::Chmod | Mode::Rename | Mode::RegexMatch => {
- tabs.selected().event_text_insertion(c)
+ status.selected().event_text_insertion(c);
+ Ok(())
}
Mode::Goto | Mode::Exec | Mode::Search => {
- tabs.selected().event_text_insert_and_complete(c)
+ status.selected().event_text_insert_and_complete(c)
}
Mode::Normal => match self.binds.get(&c) {
- Some(event_char) => event_char.match_char(tabs),
- None => (),
+ Some(event_char) => event_char.match_char(status),
+ None => Ok(()),
},
- Mode::Help | Mode::Preview | Mode::Shortcut => {
- tabs.selected().event_normal().unwrap_or_default()
- }
- Mode::Jump => (),
- Mode::History => (),
+ Mode::Help | Mode::Preview | Mode::Shortcut => status.selected().event_normal(),
+ Mode::Jump => Ok(()),
+ Mode::History => Ok(()),
Mode::NeedConfirmation => {
if c == 'y' {
- let _ = tabs.exec_last_edition();
+ let _ = status.exec_last_edition();
}
- tabs.selected().event_leave_need_confirmation()
+ status.selected().event_leave_need_confirmation();
+ Ok(())
+ }
+ Mode::Marks(MarkAction::Jump) => status.exec_marks_jump(c),
+ Mode::Marks(MarkAction::New) => status.exec_marks_new(c),
+ Mode::Sort => {
+ status.selected().event_leave_sort(c);
+ Ok(())
}
- Mode::Marks(MarkAction::Jump) => tabs.exec_marks_jump(c).unwrap_or_default(),
- Mode::Marks(MarkAction::New) => tabs.exec_marks_new(c).unwrap_or_default(),
- Mode::Sort => tabs.selected().event_leave_sort(c),
}
}
}
diff --git a/src/completion.rs b/src/completion.rs
index 1af4ac3..23f5270 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -1,6 +1,6 @@
use std::fs;
-use crate::fileinfo::PathContent;
+use crate::{fileinfo::PathContent, fm_error::FmResult};
/// Holds a `Vec<String>` of possible completions and an `usize` index
/// showing where the user is in the vec.
@@ -64,10 +64,10 @@ impl Completion {
self.proposals.clear();
}
- pub fn goto(&mut self, input_string: &str) {
+ pub fn goto(&mut self, input_string: &str) -> FmResult<()> {
let (parent, last_name) = split_input_string(input_string);
if last_name.is_empty() {
- return;
+ return Ok(());
}
if let Ok(path) = std::fs::canonicalize(parent) {
if let Ok(entries) = fs::read_dir(path) {
@@ -81,10 +81,11 @@ impl Completion {
.collect(),
)
}
- }
+ };
+ Ok(())
}
- pub fn exec(&mut self, input_string: &String) {
+ pub fn exec(&mut self, input_string: &String) -> FmResult<()> {
let mut proposals: Vec<String> = vec![];
for path in std::env::var_os("PATH")
.unwrap_or_default()
@@ -92,22 +93,21 @@ impl Completion {
.unwrap_or_default()
.split(':')
{
- if let Ok(entries) = fs::read_dir(path) {
- let comp: Vec<String> = entries
- .filter(|e| e.is_ok())
- .map(|e| e.unwrap())
- .filter(|e| {
- e.file_type().unwrap().is_file() && filename_startswith(e, input_string)
- })
- .map(|e| e.path().to_string_lossy().into_owned())
- .collect();
- proposals.extend(comp);
- }
+ let comp: Vec<String> = fs::read_dir(path)?
+ .filter(|e| e.is_ok())
+ .map(|e| e.unwrap())
+ .filter(|e| {
+ e.file_type().unwrap().is_file() && filename_startswith(e, input_string)
+ })
+ .map(|e| e.path().to_string_lossy().into_owned())
+ .collect();
+ proposals.extend(comp);
}
self.update(proposals);
+ Ok(())
}
- pub fn search(&mut self, input_string: &String, path_content: &PathContent) {
+ pub fn search(&mut self, input_string: &String, path_content: &PathContent) -> FmResult<()> {
self.update(
path_content
.files
@@ -116,6 +116,7 @@ impl Completion {
.map(|f| f.filename.clone())
.collect(),
);
+ Ok(())
}
}
diff --git a/src/display.rs b/src/display.rs
index 422c5ba..05722df 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -7,7 +7,7 @@ use tuikit::term::Term;
use crate::config::Colors;
use crate::content_window::ContentWindow;
use crate::fileinfo::fileinfo_attr;
-use crate::fm_error::FmResult;
+use crate::fm_error::{FmError, FmResult};
use crate::last_edition::LastEdition;
use crate::mode::{MarkAction, Mode};
use crate::preview::Preview;
@@ -94,7 +94,7 @@ impl Display {
"Tab: {}/{} -- Path: {} -- Files: {}",
tabs.index + 1,
tabs.len(),
- status.path_content.path_to_str(),
+ status.path_content.path_to_str()?,
status.path_content.files.len(),
)
}
@@ -178,7 +178,8 @@ impl Display {
let _ = self.term.print_with_attr(
row + ContentWindow::WINDOW_MARGIN_TOP,
4,
- path.to_str().unwrap_or_default(),
+ path.to_str()
+ .ok_or_else(|| FmError::new("Unreadable filename"))?,
attr,
);
}
@@ -197,7 +198,8 @@ impl Display {
self.term.print_with_attr(
row + ContentWindow::WINDOW_MARGIN_TOP,
4,
- path.to_str().unwrap_or_default(),
+ path.to_str()
+ .ok_or_else(|| FmError::new("Unreadable filename"))?,
attr,
)?;
}
@@ -216,7 +218,8 @@ impl Display {
let _ = self.term.print_with_attr(
row + ContentWindow::WINDOW_MARGIN_TOP,
4,
- path.to_str().unwrap_or_default(),
+ path.to_str()
+ .ok_or_else(|| FmError::new("Unreadable filename"))?,
attr,
);
}
@@ -253,7 +256,8 @@ impl Display {
self.term.print_with_attr(
row + ContentWindow::WINDOW_MARGIN_TOP + 2,
4,
- path.to_str().unwrap_or_default(),
+ path.to_str()
+ .ok_or_else(|| FmError::new("Unreadable filename"))?,
Attr::default(),
)?;
}
@@ -266,7 +270,7 @@ impl Display {
};
let content = format!(
"Files will be copied to {}",
- status.path_content.path_to_str()
+ status.path_content.path_to_str()?
);
self.term.print_with_attr(2, 3, &content, attr)?;
}
@@ -377,7 +381,7 @@ impl Display {
self.term
.print_with_attr(2, 1, "mark path", Self::ATTR_YELLOW)?;
- for (i, line) in tabs.marks.as_strings().iter().enumerate() {
+ for (i, line) in tabs.marks.as_strings()?.iter().enumerate() {
let row = Self::calc_line_row(i, status) + 2;
self.term.print(row, 3, line)?;
}
diff --git a/src/event_char.rs b/src/event_char.rs
index a83c83c..d0b3e5d 100644
--- a/src/event_char.rs
+++ b/src/event_char.rs
@@ -1,3 +1,4 @@
+use crate::fm_error::FmResult;
use crate::status::Status;
pub enum EventChar {
@@ -34,39 +35,96 @@ pub enum EventChar {
}
impl EventChar {
- pub fn match_char(&self, tabs: &mut Status) {
+ pub fn match_char(&self, tabs: &mut Status) -> FmResult<()> {
let current_status = tabs.selected();
match *self {
- EventChar::ToggleHidden => current_status.event_toggle_hidden().unwrap_or_default(),
- EventChar::CopyPaste => current_status.event_copy_paste(),
- EventChar::CutPaste => current_status.event_cur_paste(),
- EventChar::NewDir => current_status.event_new_dir(),
- EventChar::NewFile => current_status.event_new_file(),
- EventChar::Chmod => tabs.event_chmod().unwrap_or_default(),
- EventChar::Exec => current_status.event_exec(),
- EventChar::Goto => current_status.event_goto(),
- EventChar::Rename => current_status.event_rename(),
- EventChar::ClearFlags => tabs.event_clear_flags().unwrap_or_default(),
- EventChar::ToggleFlag => tabs.event_toggle_flag().unwrap_or_default(),
- EventChar::Shell => current_status.event_shell().unwrap_or_default(),
- EventChar::DeleteFile => current_status.event_delete_file(),
- EventChar::OpenFile => current_status.event_open_file().unwrap_or_default(),
- EventChar::Help => current_status.event_help(),
- EventChar::Search => current_status.event_search(),
- EventChar::RegexMatch => current_status.event_regex_match(),
- EventChar::Quit => current_status.event_quit(),
- EventChar::FlagAll => tabs.event_flag_all().unwrap_or_default(),
- EventChar::ReverseFlags => tabs.event_reverse_flags().unwrap_or_default(),
- EventChar::Jump => tabs.event_jump(),
- EventChar::History => current_status.event_history(),
- EventChar::NvimFilepicker => current_status.event_nvim_filepicker(),
- EventChar::Sort => current_status.event_sort(),
- EventChar::Symlink => tabs.event_symlink().unwrap_or_default(),
- EventChar::Preview => current_status.event_preview().unwrap_or_default(),
- EventChar::Shortcut => current_status.event_shortcut(),
- EventChar::Bulkrename => tabs.event_bulkrename().unwrap_or_default(),
- EventChar::MarksNew => tabs.event_marks_new(),
- EventChar::MarksJump => tabs.event_marks_jump(),
+ EventChar::ToggleHidden => current_status.event_toggle_hidden(),
+ EventChar::CopyPaste => {
+ current_status.event_copy_paste();
+ Ok(())
+ }
+ EventChar::CutPaste => {
+ current_status.event_cur_paste();
+ Ok(())
+ }
+ EventChar::NewDir => {
+ current_status.event_new_dir();
+ Ok(())
+ }
+ EventChar::NewFile => {
+ current_status.event_new_file();
+ Ok(())
+ }
+ EventChar::Chmod => tabs.event_chmod(),
+ EventChar::Exec => {
+ current_status.event_exec();
+ Ok(())
+ }
+ EventChar::Goto => {
+ current_status.event_goto();
+ Ok(())
+ }
+ EventChar::Rename => {
+ current_status.event_rename();
+ Ok(())
+ }
+ EventChar::ClearFlags => tabs.event_clear_flags(),
+ EventChar::ToggleFlag => tabs.event_toggle_flag(),
+ EventChar::Shell => current_status.event_shell(),
+ EventChar::DeleteFile => {
+ current_status.event_delete_file();
+ Ok(())
+ }
+ EventChar::OpenFile => current_status.event_open_file(),
+ EventChar::Help => {
+ current_status.event_help();
+ Ok(())
+ }
+ EventChar::Search => {
+ current_status.event_search();
+ Ok(())
+ }
+ EventChar::RegexMatch => {
+ current_status.event_regex_match();
+ Ok(())
+ }
+ EventChar::Quit => {
+ current_status.event_quit();
+ Ok(())
+ }
+ EventChar::FlagAll => tabs.event_flag_all(),
+ EventChar::ReverseFlags => tabs.event_reverse_flags(),
+ EventChar::Jump => {
+ tabs.event_jump();
+ Ok(())
+ }
+ EventChar::History => {
+ current_status.event_history();
+ Ok(())
+ }
+ EventChar::NvimFilepicker => {
+ current_status.event_nvim_filepicker();
+ Ok(())
+ }
+ EventChar::Sort => {
+ current_status.event_sort();
+ Ok(())
+ }
+ EventChar::Symlink => tabs.event_symlink(),
+ EventChar::Preview => current_status.event_preview(),
+ EventChar::Shortcut => {
+ current_status.event_shortcut();
+ Ok(())
+ }
+ EventChar::Bulkrename => tabs.event_bulkrename(),
+ EventChar::MarksNew => {
+ tabs.event_marks_new();
+ Ok(())
+ }
+ EventChar::MarksJump => {
+ tabs.event_marks_jump();
+ Ok(())
+ }
}
}
}
diff --git a/src/fileinfo.rs b/src/fileinfo.rs
index 6d77398..4c6207f 100644
--- a/src/fileinfo.rs
+++ b/src/fileinfo.rs
@@ -141,9 +141,7 @@ impl FileInfo {
let file_kind = FileKind::new(direntry);
let dir_symbol = file_kind.extract_dir_symbol();
- let extension = extract_extension_from_filename(&filename)
- .unwrap_or("")
- .into();
+ let extension = extract_extension_from_filename(&filename).into();
Ok(FileInfo {
path,
@@ -243,8 +241,10 @@ impl PathContent {
Ok(files)
}
- pub fn path_to_str(&self) -> &str {
- self.path.to_str().unwrap_or_default()
+ pub fn path_to_str(&self) -> FmResult<&str> {
+ self.path
+ .to_str()
+ .ok_or_else(|| FmError::new("Unreadable path"))
}
/// Sort the file with current key.
@@ -366,18 +366,18 @@ fn is_not_hidden(entry: &DirEntry) -> Result<bool, FmError> {
}
/// Returns the modified time.
-fn extract_datetime(direntry: &DirEntry) -> Result<String, FmError> {
+fn extract_datetime(direntry: &DirEntry) -> FmResult<String> {
let datetime: DateTime<Local> = direntry.metadata()?.modified()?.into();
Ok(format!("{}", datetime.format("%d/%m/%Y %T")))
}
/// Returns the filename.
-fn extract_filename(direntry: &DirEntry) -> Result<String, FmError> {
+fn extract_filename(direntry: &DirEntry) -> FmResult<String> {
Ok(direntry.file_name().into_string()?)
}
/// Reads the permission and converts them into a string.
-fn extract_permissions_string(direntry: &DirEntry) -> Result<String, FmError> {
+fn extract_permissions_string(direntry: &DirEntry) -> FmResult<String> {
let metadata = metadata(direntry.path())?;
let mode = metadata.mode() & 511;
let s_o = convert_octal_mode(mode >> 6);
@@ -393,7 +393,7 @@ fn convert_octal_mode(mode: u32) -> String {
}
/// Reads the owner name and returns it as a string.
-fn extract_owner(direntry: &DirEntry) -> Result<String, FmError> {
+fn extract_owner(direntry: &DirEntry) -> FmResult<String> {
Ok(String::from(
get_user_by_uid(metadata(direntry.path())?.uid())
.ok_or_else(|| FmError::new("Couldn't read uid"))?
@@ -420,8 +420,10 @@ fn human_size(bytes: u64) -> String {
}
/// Extract the optional extension from a filename.
-fn extract_extension_from_filename(filename: &str) -> Option<&str> {
+/// Returns empty &str aka "" if the file has no extension.
+fn extract_extension_from_filename(filename: &str) -> &str {
path::Path::new(filename)
.extension()
.and_then(std::ffi::OsStr::to_str)
+ .unwrap_or_default()
}
diff --git a/src/main.rs b/src/main.rs
index c415135..daaa8cc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -36,7 +36,7 @@ fn main() -> FmResult<()> {
while let Ok(event) = display.term.poll_event() {
let _ = display.term.clear();
- let (_width, height) = display.term.term_size().unwrap();
+ let (_width, height) = display.term.term_size()?;
status.selected().set_height(height);
@@ -44,7 +44,7 @@ fn main() -> FmResult<()> {
display.display_all(&status)?;
- let _ = display.term.present();
+ display.term.present()?;
if status.selected().must_quit() {
reset_cursor(&display)?;
diff --git a/src/marks.rs b/src/marks.rs
index 6fa68ab..7a079ad 100644
--- a/src/marks.rs
+++ b/src/marks.rs
@@ -4,6 +4,7 @@ use std::fs::OpenOptions;
use std::io::{self, BufRead, BufWriter, Error, ErrorKind, Write};
use std::path::{Path, PathBuf};
+use crate::fm_error::FmError;
use crate::fm_error::FmResult;
static MARKS_FILEPATH: &str = "~/.config/fm/marks.cfg";
@@ -64,29 +65,36 @@ impl Marks {
let mut buf = BufWriter::new(file);
for (ch, path) in self.marks.iter() {
- let _ = write!(buf, "{}:{}", ch, Self::path_as_string(path));
+ let _ = write!(buf, "{}:{}", ch, Self::path_as_string(path)?);
}
Ok(())
}
- fn path_as_string(path: &Path) -> String {
- path.to_str().unwrap_or("").to_owned()
+ fn path_as_string(path: &Path) -> FmResult<String> {
+ Ok(path
+ .to_str()
+ .ok_or_else(|| FmError::new("Unreadable path"))?
+ .to_owned())
}
- pub fn as_strings(&self) -> Vec<String> {
- self.marks
+ pub fn as_strings(&self) -> FmResult<Vec<String>> {
+ Ok(self
+ .marks
.iter()
- .map(|(ch, path)| Self::format_mark(ch, path))
- .collect()
+ .map(|(ch, path)| Self::format_mark(ch, path).unwrap_or_default())
+ .collect())
}
- fn format_mark(ch: &char, path: &Path) -> String {
+ fn format_mark(ch: &char, path: &Path) -> FmResult<String> {
let mut s = "".to_owned();
s.push(*ch);
s.push_str(" ");
- s.push_str(path.to_str().unwrap_or(""));
+ s.push_str(
+ path.to_str()
+ .ok_or_else(|| FmError::new("Unreadable path"))?,
+ );
s.push('\n');
- s
+ Ok(s)
}
}
diff --git a/src/status.rs b/src/status.rs
index 7db0afa..888a309 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -164,11 +164,14 @@ impl Status {
}
}
- pub fn event_toggle_flag(&mut self) -> Option<()> {
- let file = self.statuses[self.index].path_content.selected_file()?;
+ pub fn event_toggle_flag(&mut self) -> FmResult<()> {
+ let file = self.statuses[self.index]
+ .path_content
+ .selected_file()
+ .ok_or_else(|| FmError::new("No selected file"))?;
self.toggle_flag_on_path(file.path.clone());
self.selected().event_down_one_row();
- Some(())
+ Ok(())