summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-12-20 22:07:38 +0100
committerrabite <rabite@posteo.de>2019-12-20 22:07:38 +0100
commit03693f96d0265f665ec00b5bb204cb727d7b137a (patch)
tree0e9e7f01e7eaff33f764c76a3a09c0fc84f02d60
parent0525f37c6964e43cc82dd548bd7ac460c7c84601 (diff)
improved Files interface by returning Iterator instead of Vec<&File>
-rw-r--r--src/file_browser.rs26
-rw-r--r--src/files.rs59
-rw-r--r--src/listview.rs41
3 files changed, 73 insertions, 53 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 1a57c8a..257ca32 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -441,11 +441,11 @@ impl FileBrowser {
pub fn move_down_left_widget(&mut self) -> HResult<()> {
let left_files_pos = self.left_widget()?.get_selection();
- let next_dir = self.get_left_files()?.get_files()
- .iter()
+ let next_dir = self.get_left_files()?
+ .iter_files()
.skip(left_files_pos + 1)
- .find(|file| file.is_dir())
- .cloned().cloned();
+ .find(|&file| file.is_dir())
+ .cloned();
self.main_widget_goto(&next_dir?).log();
@@ -454,14 +454,15 @@ impl FileBrowser {
pub fn move_up_left_widget(&mut self) -> HResult<()> {
let left_files_pos = self.left_widget()?.get_selection();
- let skip_files = self.get_left_files()?.len() - left_files_pos;
- let next_dir = self.get_left_files()?.get_files()
- .iter()
+ let next_dir = self.get_left_files()?
+ .iter_files()
+ .take(left_files_pos)
+ .collect::<Vec<&File>>()
+ .into_iter()
.rev()
- .skip(skip_files)
- .find(|file| file.is_dir())
- .cloned().cloned();
+ .find(|&file| file.is_dir())
+ .cloned();
self.main_widget_goto(&next_dir?).log();
@@ -1170,7 +1171,10 @@ impl FileBrowser {
let xsize = self.get_coordinates()?.xsize();
let ypos = self.get_coordinates()?.position().y();
let pos = self.main_widget()?.get_selection();
- let file = self.main_widget()?.content.get_files().get(pos).cloned()?;
+ let file = self.main_widget()?
+ .content
+ .iter_files()
+ .nth(pos)?;
let permissions = file.pretty_print_permissions().unwrap_or("NOPERMS".into());
let user = file.pretty_user().unwrap_or("NOUSER".into());
diff --git a/src/files.rs b/src/files.rs
index fa774c5..d8558af 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -238,48 +238,54 @@ impl Files {
}
pub fn get_file_mut(&mut self, index: usize) -> Option<&mut File> {
+ self.iter_files_mut()
+ .nth(index)
+ }
+
+ pub fn iter_files(&self) -> impl Iterator<Item=&File> {
let filter = self.filter.clone();
let filter_selected = self.filter_selected;
let show_hidden = self.show_hidden;
- let file = self.files
- .iter_mut()
- .filter(|f|
+ self.files
+ .iter()
+ .filter(move |f|
f.kind == Kind::Placeholder ||
!(filter.is_some() &&
!f.name.contains(filter.as_ref().unwrap())) &&
(!filter_selected || f.selected))
- .filter(|f| !(!show_hidden && f.name.starts_with(".")))
- .nth(index);
- file
+ .filter(move |f| !(!show_hidden && f.name.starts_with(".")))
}
- pub fn get_files(&self) -> Vec<&File> {
+ pub fn iter_files_mut(&mut self) -> impl Iterator<Item=&mut File> {
+ let filter = self.filter.clone();
+ let filter_selected = self.filter_selected;
+ let show_hidden = self.show_hidden;
+
self.files
- .iter()
- .filter(|f|
+ .iter_mut()
+ .filter(move |f|
f.kind == Kind::Placeholder ||
- !(self.filter.is_some() &&
- !f.name.contains(self.filter.as_ref().unwrap())) &&
- (!self.filter_selected || f.selected))
- .filter(|f| !(!self.show_hidden && f.name.starts_with(".")))
- .collect()
+ !(filter.is_some() &&
+ !f.name.contains(filter.as_ref().unwrap())) &&
+ (!filter_selected || f.selected))
+ .filter(move |f| !(!show_hidden && f.name.starts_with(".")))
}
- pub fn get_files_mut(&mut self) -> Vec<&mut File> {
- let filter = self.filter.clone();
+ #[allow(trivial_bounds)]
+ pub fn into_iter_files(self) -> impl Iterator<Item=File> {
+ let filter = self.filter;
let filter_selected = self.filter_selected;
let show_hidden = self.show_hidden;
self.files
- .iter_mut()
- .filter(|f|
+ .into_iter()
+ .filter(move |f|
f.kind == Kind::Placeholder ||
!(filter.is_some() &&
!f.name.contains(filter.as_ref().unwrap())) &&
(!filter_selected || f.selected))
- .filter(|f| !(!show_hidden && f.name.starts_with(".")))
- .collect()
+ .filter(move |f| !(!show_hidden && f.name.starts_with(".")))
}
pub fn sort(&mut self) {
@@ -454,10 +460,8 @@ impl Files {
}
pub fn find_file_with_name(&self, name: &str) -> Option<&File> {
- self.get_files()
- .iter()
+ self.iter_files()
.find(|f| f.name.to_lowercase().contains(name))
- .cloned()
}
pub fn find_file_with_path(&mut self, path: &Path) -> Option<&mut File> {
@@ -543,15 +547,12 @@ impl Files {
}
pub fn len(&self) -> usize {
- self.get_files().len()
+ self.iter_files().count()
}
- pub fn get_selected(&self) -> Vec<&File> {
- self.get_files()
- .iter()
+ pub fn get_selected(&self) -> impl Iterator<Item=&File> {
+ self.iter_files()
.filter(|f| f.is_selected())
- .map(|f| *f)
- .collect()
}
}
diff --git a/src/listview.rs b/src/listview.rs
index 53cbff6..f44a705 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -222,14 +222,31 @@ impl ListView<Files>
{
pub fn selected_file(&self) -> &File {
let selection = self.selection;
- let file = &self.content.get_files()[selection];
- file
+
+ &self.content
+ .iter_files()
+ .nth(selection)
+ .unwrap_or(&self.content.directory)
}
pub fn selected_file_mut(&mut self) -> &mut File {
let selection = self.selection;
- let file = self.content.get_file_mut(selection);
- file.unwrap()
+
+ let file = self.content
+ .iter_files_mut()
+ .nth(selection)
+ .map(|f| f as *mut File);
+
+
+ // Work around annoying restriction until polonius borrow checker becomes default
+ // Since we only ever return one mutable borrow this is perfectly safe
+ // See also: https://github.com/rust-lang/rust/issues/21906
+ match file {
+ Some(file) => unsafe { return file.as_mut().unwrap() },
+ None => {
+ &mut self.content.directory
+ }
+ }
}
pub fn clone_selected_file(&self) -> File {
@@ -271,9 +288,8 @@ impl ListView<Files>
pub fn select_file(&mut self, file: &File) {
let pos = self
.content
- .get_files()
- .iter()
- .position(|item| item == &file)
+ .iter_files()
+ .position(|item| item == file)
.unwrap_or(0);
self.set_selection(pos);
}
@@ -308,7 +324,7 @@ impl ListView<Files>
self.select_file(&file);
- if self.seeking == false || self.selection + 1 == self.content.len() {
+ if self.seeking == false || self.selection + 1 >= self.content.len() {
self.selection = 0;
self.offset = 0;
} else {
@@ -390,7 +406,7 @@ impl ListView<Files>
}
pub fn invert_selection(&mut self) {
- for file in self.content.get_files_mut() {
+ for file in self.content.iter_files_mut() {
file.toggle_selection();
}
@@ -404,7 +420,7 @@ impl ListView<Files>
}
pub fn clear_selections(&mut self) {
- for file in self.content.get_files_mut() {
+ for file in self.content.iter_files_mut() {
file.selected = false;
}
self.content.set_dirty();
@@ -632,9 +648,8 @@ impl ListView<Files>
fn render(&self) -> Vec<String> {
self.content
- .get_files()
- .iter()
- .map(|file| self.render_line(&file))
+ .iter_files()
+ .map(|file| self.render_line(file))
.collect()
}
}