summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-05-11 13:29:00 +0200
committerrabite <rabite@posteo.de>2019-05-11 13:32:22 +0200
commit99980ace6c0935d2ebf4ddda21499702dfacde76 (patch)
tree6ac8af07e60628199a8d19c897f13caaf1662669
parent01d0c1d3381a165708f3c193332e927a66fd8d80 (diff)
use async_value library
-rw-r--r--Cargo.lock20
-rw-r--r--Cargo.toml1
-rw-r--r--rust-toolchain2
-rw-r--r--src/fail.rs55
-rw-r--r--src/file_browser.rs103
-rw-r--r--src/files.rs91
-rw-r--r--src/fscache.rs21
-rw-r--r--src/main.rs2
-rw-r--r--src/preview.rs364
-rw-r--r--src/proclist.rs13
-rw-r--r--src/widget.rs20
11 files changed, 261 insertions, 431 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ece9cca..4e93349 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,6 +39,18 @@ dependencies = [
]
[[package]]
+name = "async_value"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objekt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "autocfg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -254,6 +266,7 @@ name = "hunter"
version = "1.1.3"
dependencies = [
"alphanumeric-sort 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "async_value 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs-2 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -477,6 +490,11 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "objekt"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "ordermap"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -891,6 +909,7 @@ dependencies = [
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
+"checksum async_value 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4cd683ef2421e8767b2a0c02b105707812a98a4e1eb0559f615a15e3a80183"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
"checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637"
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
@@ -943,6 +962,7 @@ dependencies = [
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
+"checksum objekt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2069a3ae3dad97a4ae47754e8f47e5d2f1fd32ab7ad8a84bb31d051faa59cc3c"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum osstrtools 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63557d11f265b66ffcda9cc624d5f92315cfeebb7ee01c76257f890f7d730f5b"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
diff --git a/Cargo.toml b/Cargo.toml
index ba3a4ae..4866532 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,6 +31,7 @@ signal-notify = "0.1.3"
systemstat = "0.1.4"
osstrtools = "0.1"
pathbuftools = "0.1"
+async_value = "0.2.2"
[patch.crates-io]
systemstat = { git = 'https://github.com/myfreeweb/systemstat' }
diff --git a/rust-toolchain b/rust-toolchain
index 11e142a..d8d61dd 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1 +1 @@
-nightly-2019-03-15
+nightly-2019-04-28
diff --git a/src/fail.rs b/src/fail.rs
index d34ed76..c8b4e70 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -1,6 +1,8 @@
use failure;
use failure::Fail;
//use failure::Backtrace;
+use async_value::AError;
+
use termion::event::Key;
@@ -47,6 +49,8 @@ pub enum HError {
AsyncAlreadyStartedError,
#[fail(display = "Async Error: {}", _0)]
AsyncError(String),
+ #[fail(display = "Async Error: {}", _0)]
+ AError(async_value::AError),
#[fail(display = "No widget found")]
NoWidgetError,
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
@@ -209,7 +213,6 @@ pub trait ErrorLog where Self: Sized {
impl<T> ErrorLog for HResult<T> {
fn log(self) {
if let Err(err) = self {
- // eprintln!("{:?}", err);
put_log(&err).ok();
}
}
@@ -223,101 +226,97 @@ impl<T> ErrorLog for HResult<T> {
}
+impl<T> ErrorLog for Result<T, AError> {
+ fn log(self) {
+ if let Err(err) = self {
+ put_log(&err.into()).ok();
+ }
+ }
+
+ fn log_and(self) -> Self {
+ if let Err(err) = &self {
+ put_log(&err.clone().into()).ok();
+ }
+ self
+ }
+}
+
-// impl From<&HError> for HError {
-// fn from(error: &HError) -> Self {
-// dbg!(&error);
-// (error.clone())
-// }
-// }
impl From<std::io::Error> for HError {
fn from(error: std::io::Error) -> Self {
- // dbg!(&error);
let err = HError::IoError(format!("{}", error));
- put_log(&err).ok();
err
}
}
impl From<failure::Error> for HError {
fn from(error: failure::Error) -> Self {
- // dbg!(&error);
let err = HError::Error(format!("{}", error));
- put_log(&err).ok();
err
}
}
impl From<std::sync::mpsc::TryRecvError> for HError {
fn from(error: std::sync::mpsc::TryRecvError) -> Self {
- // dbg!(&error);
let err = HError::ChannelTryRecvError { error: error };
- put_log(&err).ok();
err
}
}
impl From<std::sync::mpsc::RecvError> for HError {
fn from(error: std::sync::mpsc::RecvError) -> Self {
- // dbg!(&error);
let err = HError::ChannelRecvError { error: error };
- put_log(&err).ok();
err
}
}
impl<T> From<std::sync::mpsc::SendError<T>> for HError {
- fn from(error: std::sync::mpsc::SendError<T>) -> Self {
- dbg!(&error);
+ fn from(_error: std::sync::mpsc::SendError<T>) -> Self {
let err = HError::ChannelSendError;
- put_log(&err).ok();
err
}
}
impl<T> From<std::sync::PoisonError<T>> for HError {
fn from(_: std::sync::PoisonError<T>) -> Self {
- // dbg!("Poisoned Mutex");
let err = HError::MutexError;
- put_log(&err).ok();
err
}
}
impl<T> From<std::sync::TryLockError<T>> for HError {
fn from(_error: std::sync::TryLockError<T>) -> Self {
- // dbg!(&error);
let err = HError::TryLockError;
- put_log(&err).ok();
err
}
}
impl From<std::option::NoneError> for HError {
fn from(_error: std::option::NoneError) -> Self {
- //dbg!(&error);
let err = HError::NoneError;
- //put_log(&err).ok();
err
}
}
impl From<std::path::StripPrefixError> for HError {
fn from(error: std::path::StripPrefixError) -> Self {
- // dbg!(&error);
let err = HError::StripPrefixError{error: error };
- put_log(&err).ok();
err
}
}
impl From<notify::Error> for HError {
fn from(error: notify::Error) -> Self {
- // dbg!(&error);
let err = HError::INotifyError(format!("{}", error));
- put_log(&err).ok();
+ err
+ }
+}
+
+impl From<async_value::AError> for HError {
+ fn from(error: async_value::AError) -> Self {
+ let err = HError::AError(error);
err
}
}
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 34ab2a6..cdd2284 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -1,6 +1,7 @@
use termion::event::Key;
use pathbuftools::PathBufTools;
use osstrtools::OsStrTools;
+use async_value::Stale;
use std::io::Write;
use std::sync::{Arc, Mutex, RwLock};
@@ -196,24 +197,33 @@ impl Tabbable for TabView<FileBrowser> {
}
fn on_config_loaded(&mut self) -> HResult<()> {
- // hack: wait a bit for widget readyness...
- let duration = std::time::Duration::from_millis(100);
- std::thread::sleep(duration);
-
let show_hidden = self.config().show_hidden();
+
for tab in self.widgets.iter_mut() {
- tab.left_widget_mut().map(|w| {
- w.content.show_hidden = show_hidden;
- w.content.dirty_meta.set_dirty();
- w.refresh().log();
- }).ok();
-
- tab.main_widget_mut().map(|w| {
- w.content.show_hidden = show_hidden;
- w.content.dirty_meta.set_dirty();
- w.content.sort();
- w.refresh().log();
- }).ok();
+ tab.left_async_widget_mut().map(|async_w| {
+ async_w.widget.on_ready(move |mut w, _| {
+ w.as_mut()
+ .map(|mut w| {
+ w.content.show_hidden = show_hidden;
+ w.content.dirty_meta.set_dirty();
+ w.refresh().log();
+ }).ok();
+ Ok(())
+ }).log();
+ }).log();
+
+ tab.main_async_widget_mut().map(|async_w| {
+ async_w.widget.on_ready(move |mut w, _| {
+ w.as_mut()
+ .map(|mut w| {
+ w.content.show_hidden = show_hidden;
+ w.content.dirty_meta.set_dirty();
+ w.content.sort();
+ w.refresh().log();
+ }).ok();
+ Ok(())
+ }).log()
+ }).log();
tab.preview_widget_mut().map(|w| w.config_loaded()).ok();
}
@@ -252,7 +262,7 @@ impl FileBrowser {
let left_path = main_path.parent().map(|p| p.to_path_buf());
let cache = fs_cache.clone();
- let main_widget = AsyncWidget::new(&core, Box::new(move |_| {
+ let main_widget = AsyncWidget::new(&core, move |_| {
let name = if main_path.parent().is_none() {
"root".to_string()
} else {
@@ -277,11 +287,11 @@ impl FileBrowser {
list.refresh().log();
Ok(list)
- }));
+ });
let cache = fs_cache.clone();
if let Some(left_path) = left_path {
- let left_widget = AsyncWidget::new(&core, Box::new(move |_| {
+ let left_widget = AsyncWidget::new(&core, move |_| {
let name = if left_path.parent().is_none() {
"root".to_string()
} else {
@@ -303,14 +313,14 @@ impl FileBrowser {
list.refresh().log();
Ok(list)
- }));
+ });
let left_widget = FileBrowserWidgets::FileList(left_widget);
columns.push_widget(left_widget);
} else {
- let left_widget = AsyncWidget::new(&core, Box::new(move |_| {
+ let left_widget = AsyncWidget::new(&core, move |_| {
let blank = TextView::new_blank(&core_l);
Ok(blank)
- }));
+ });
let left_widget = FileBrowserWidgets::Blank(left_widget);
columns.push_widget(left_widget);
@@ -372,7 +382,7 @@ impl FileBrowser {
let core = self.core.clone();
let cache = self.fs_cache.clone();
- let main_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let main_widget = AsyncWidget::new(&core.clone(), move |_| {
let files = match previewer_files {
Some(files) => files,
None => cache.get_files_sync(&dir)?
@@ -389,7 +399,7 @@ impl FileBrowser {
list.content.meta_all();
Ok(list)
- }));
+ });
let main_widget = FileBrowserWidgets::FileList(main_widget);
self.columns.insert_widget(1, main_widget);
@@ -492,9 +502,9 @@ impl FileBrowser {
self.cwd = dir.clone();
let main_async_widget = self.main_async_widget_mut()?;
- main_async_widget.change_to(Box::new(move |stale, core| {
- let (selected_file, files) = cache.get_files(&dir, stale)?;
- let files = files.wait()?;
+ main_async_widget.change_to(move |stale: &Stale, core| {
+ let (selected_file, files) = cache.get_files(&dir, stale.clone())?;
+ let files = files.run_sync()?;
let mut list = ListView::new(&core, files);
@@ -505,14 +515,14 @@ impl FileBrowser {
list.select_file(&file);
}
Ok(list)
- })).log();
+ }).log();
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
self.left_widget_goto(&grand_parent).log();
} else {
- self.left_async_widget_mut()?.change_to(Box::new(move |_,_| {
+ self.left_async_widget_mut()?.change_to(move |_,_| {
HError::stale()?
- })).log();
+ }).log();
}
Ok(())
@@ -530,15 +540,15 @@ impl FileBrowser {
let dir = dir.clone();
let left_async_widget = self.left_async_widget_mut()?;
- left_async_widget.change_to(Box::new(move |stale, core| {
- let cached_files = cache.get_files(&dir, stale)?;
+ left_async_widget.change_to(move |stale, core| {
+ let cached_files = cache.get_files(&dir, stale.clone())?;
let (_, files) = cached_files;
- let files = files.wait()?;
+ let files = files.run_sync()?;
let list = ListView::new(&core, files);
Ok(list)
- }))?;
+ })?;
Ok(())
}
@@ -552,19 +562,19 @@ impl FileBrowser {
if let Ok(left_dir) = new_cwd.parent_as_file() {
let cache = self.fs_cache.clone();
- let left_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let left_widget = AsyncWidget::new(&core.clone(), move |_| {
let files = cache.get_files_sync(&left_dir)?;
let list = ListView::new(&core, files);
Ok(list)
- }));
+ });
let left_widget = FileBrowserWidgets::FileList(left_widget);
self.columns.prepend_widget(left_widget);
} else {
- let left_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let left_widget = AsyncWidget::new(&core.clone(), move |_| {
let blank = TextView::new_blank(&core);
Ok(blank)
- }));
+ });
let left_widget = FileBrowserWidgets::Blank(left_widget);
self.columns.prepend_widget(left_widget);
@@ -669,9 +679,9 @@ impl FileBrowser {
pub fn take_main_files(&mut self) -> HResult<Files> {
let core = self.core.clone();
- let blank = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let blank = AsyncWidget::new(&core.clone(), move |_| {
HError::no_files()
- }));
+ });
let blank = FileBrowserWidgets::Blank(blank);
let old_widget = self.columns.replace_widget(1, blank);
@@ -685,9 +695,9 @@ impl FileBrowser {
pub fn take_left_files(&mut self) -> HResult<Files> {
let core = self.core.clone();
- let blank = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let blank = AsyncWidget::new(&core.clone(), move |_| {
HError::no_files()
- }));
+ });
let blank = FileBrowserWidgets::FileList(blank);
let old_widget = self.columns.replace_widget(0, blank);
@@ -930,9 +940,14 @@ impl FileBrowser {
let file = File::new_from_path(&path, None)?;
let dir = file.parent_as_file()?;
- self.main_widget_goto_wait(&dir).log();
+ self.main_widget_goto(&dir).log();
- self.main_widget_mut()?.select_file(&file);
+ self.main_async_widget_mut()?
+ .widget
+ .on_ready(move |w, _| {
+ w?.select_file(&file);
+ Ok(())
+ })?;
}
} else {
let msg = format!("Can't access path: {}!",
diff --git a/src/files.rs b/src/files.rs
index a5b9b46..17b2612 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -19,10 +19,10 @@ use notify::DebouncedEvent;
use rayon::{ThreadPool, ThreadPoolBuilder};
use alphanumeric_sort::compare_str;
use pathbuftools::PathBufTools;
+use async_value::{Async, Stale};
use crate::fail::{HResult, HError, ErrorLog};
use crate::dirty::{AsyncDirtyBit, DirtyBit, Dirtyable};
-use crate::preview::{Async, Stale};
use crate::widget::Events;
use crate::icon::Icons;
@@ -186,7 +186,7 @@ impl Files {
let files: Vec<_> = direntries?
.iter()
.map(|file| {
- if crate::preview::is_stale(&stale).unwrap() {
+ if stale.is_stale().ok()? {
None
} else {
let name = file.file_name();
@@ -202,7 +202,7 @@ impl Files {
.flatten()
.collect();
- if crate::preview::is_stale(&stale).unwrap() {
+ if stale.is_stale()? {
return Err(crate::fail::HError::StalePreviewError {
file: path.to_string_lossy().to_string()
})?;
@@ -580,8 +580,15 @@ impl Hash for File {
impl Eq for File {}
+impl std::fmt::Debug for File {
+ fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ write!(formatter, "{:?}", self.path)
+ }
+}
+
-#[derive(Clone, Debug)]
+
+#[derive(Clone)]
pub struct File {
pub name: String,
pub path: PathBuf,
@@ -682,23 +689,20 @@ impl File {
stale_preview: Option<Stale>) -> Async<Metadata> {
let path = path.clone();
- let meta_closure = Box::new(move |stale: Stale| {
+ let mut meta = Async::new(move |stale: &Stale| {
if stale.is_stale()? { HError::stale()? }
Ok(std::fs::symlink_metadata(&path)?)
});
- let mut meta = match stale_preview {
- Some(stale) => Async::new_with_stale(meta_closure, stale),
- None => Async::new(meta_closure)
- };
- if let Some(dirty_meta) = dirty_meta {
- meta.on_ready(Box::new(move || {
- let mut dirty_meta = dirty_meta.clone();
- dirty_meta.set_dirty();
+ stale_preview.map(|s| meta.put_stale(s));
+
+ dirty_meta.map(|mut d|
+ meta.on_ready(move |_,_| {
+ d.set_dirty();
Ok(())
- }));
- }
+ }).log()
+ );
meta
}
@@ -707,29 +711,25 @@ impl File {
stale_preview: Option<Stale>) -> Async<usize> {
let path = path.clone();
- let dirsize_closure = Box::new(move |stale: Stale| {
+ let mut dirsize = Async::new(move |stale: &Stale| {
if stale.is_stale()? { HError::stale()? }
Ok(std::fs::read_dir(&path)?.count())
});
- let mut dirsize = match stale_preview {
- Some(stale) => Async::new_with_stale(dirsize_closure, stale),
- None => Async::new(dirsize_closure)
- };
+ stale_preview.map(|s| dirsize.put_stale(s));
- if let Some(dirty_meta) = dirty_meta {
- dirsize.on_ready(Box::new(move || {
- let mut dirty_meta = dirty_meta.clone();
- dirty_meta.set_dirty();
+ dirty_meta.map(|mut d|
+ dirsize.on_ready(move |_,_| {
+ d.set_dirty();
Ok(())
- }));
- }
+ }).log()
+ );
dirsize
}
pub fn meta(&self) -> HResult<&Metadata> {
- self.meta.get()
+ Ok(self.meta.get()?)
}
fn take_dirsize(&mut self,
@@ -738,13 +738,15 @@ impl File {
let dirsize = self.dirsize.as_mut()?;
if let Ok(_) = dirsize.value { return Ok(()) }
- match dirsize.take_async() {
- Ok(_) => { *meta_updated = true; },
- Err(HError::AsyncNotReadyError) => { dirsize.run_pooled(&*pool).ok(); },
- Err(HError::AsyncAlreadyTakenError) => {},
- Err(HError::NoneError) => {},
- err @ Err(_) => { err?; }
+ if !dirsize.is_running() {
+ dirsize.run_pooled(Some(&*pool))?;
}
+
+ if dirsize.is_ready() {
+ dirsize.pull_async()?;
+ *meta_updated = true;
+ }
+
Ok(())
}
@@ -753,15 +755,15 @@ impl File {
meta_updated: &mut bool) -> HResult<()> {
if self.meta_processed { return Ok(()) }
- match self.meta.take_async() {
- Ok(_) => { *meta_updated = true; },
- Err(HError::AsyncNotReadyError) => { self.meta.run_pooled(&*pool).ok(); },
- Err(HError::AsyncAlreadyTakenError) => {},
- Err(HError::NoneError) => {},
- err @ Err(_) => { err?; }
+ if !self.meta.is_running() {
+ self.meta.run_pooled(Some(&*pool))?;
}
- self.process_meta()?;
+ if self.meta.is_ready() {
+ self.meta.pull_async()?;
+ self.process_meta()?;
+ *meta_updated = true;
+ }
Ok(())
}
@@ -785,12 +787,13 @@ impl File {
self.meta = File::make_async_meta(&self.path,
self.dirty_meta.clone(),
None);
- self.meta.run().log();
+ self.meta.run()?;
if self.dirsize.is_some() {
- self.dirsize
- = Some(File::make_async_dirsize(&self.path, self.dirty_meta.clone(), None));
- self.dirsize.as_mut()?.run().log();
+ self.dirsize = Some(File::make_async_dirsize(&self.path,
+ self.dirty_meta.clone(),
+ None));
+ self.dirsize.as_mut()?.run()?;
}
Ok(())
}
diff --git a/src/fscache.rs b/src/fscache.rs
index 1c5ab17..d92caab 100644
--- a/src/fscache.rs
+++ b/src/fscache.rs
@@ -1,12 +1,13 @@
use notify::{RecommendedWatcher, Watcher, DebouncedEvent, RecursiveMode};
+use async_value::{Async, Stale};
+
use std::sync::{Arc, RwLock};
use std::sync::mpsc::{channel, Sender, Receiver};
use std::collections::{HashMap, HashSet};
use std::time::Duration;
use std::path::PathBuf;
-use crate::preview::{Async, Stale};
use crate::files::{Files, File, SortBy};
use crate::widget::Events;
use crate::fail::{HResult, HError, ErrorLog};
@@ -116,11 +117,11 @@ impl FsCache {
let dir = dir.clone();
let selection = self.get_selection(&dir).ok();
let cache = self.clone();
- let files = Async::new(Box::new(move |_| {
+ let files = Async::new(move |_| {
let mut files = Files::new_from_path_cancellable(&dir.path, stale)?;
FsCache::apply_settingss(&cache, &mut files).ok();
Ok(files)
- }));
+ });
Ok((selection, files))
}
}
@@ -128,7 +129,7 @@ impl FsCache {
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
self.add_watch(&dir).log();
let files = self.get_files(&dir, Stale::new())?.1;
- let mut files = files.wait()?;
+ let mut files = files.run_sync()?;
FsCache::apply_settingss(&self, &mut files).ok();
let files = FsCache::ensure_not_empty(files)?;
Ok(files)
@@ -210,8 +211,12 @@ impl FsCache {
let file_cache = self.files.clone();
let dir = dir.clone();
- let files = Async::new(Box::new(move |_| {
- let mut files = file_cache.read()?.get(&dir)?.clone();
+ let files = Async::new(move |_| {
+ let mut files = file_cache.read()
+ .map_err(|e| HError::from(e))?
+ .get(&dir)
+ .ok_or(HError::NoneError)?
+ .clone();
let tab_settings = &tab_settings;
files.sort = tab_settings.dir_settings.sort;
@@ -233,7 +238,7 @@ impl FsCache {
files.sort();
let files = FsCache::ensure_not_empty(files)?;
Ok(files)
- }));
+ });
Ok((selection, files))
}
@@ -301,7 +306,7 @@ fn watch_fs(rx_fs_events: Receiver<DebouncedEvent>,
for event in rx_fs_events.iter() {
apply_event(&fs_cache, &fs_changes, event).log();
- Ok(sender.send(Events::WidgetReady)?).log();
+ sender.send(Events::WidgetReady).ok();
}
Ok(())
});
diff --git a/src/main.rs b/src/main.rs
index 1a06eb0..4df39ab 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,6 @@
#![feature(vec_remove_item)]
#![feature(trivial_bounds)]
#![feature(try_trait)]
-#![feature(fnbox)]
#![allow(dead_code)]
extern crate termion;
@@ -24,6 +23,7 @@ extern crate tree_magic;
extern crate systemstat;
extern crate osstrtools;
extern crate pathbuftools;
+extern crate async_value;
use failure::Fail;
diff --git a/src/preview.rs b/src/preview.rs
index b833c00..08e10c3 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -1,7 +1,6 @@
-use std::sync::{Arc, Mutex, RwLock};
-use std::boxed::FnBox;
+use std::sync::{Arc, Mutex};
-use rayon::ThreadPool;
+use async_value::{Async, Stale};
use crate::files::{File, Files, Kind};
use crate::fscache::FsCache;
@@ -13,14 +12,8 @@ use crate::fail::{HResult, HError, ErrorLog};
use crate::dirty::Dirtyable;
-pub type AsyncValueFn<T> = Box<dyn FnBox(Stale) -> HResult<T> + Send + Sync>;
-pub type AsyncValue<T> = Arc<Mutex<Option<HResult<T>>>>;
-pub type AsyncReadyFn = Box<dyn FnBox() -> HResult<()> + Send + Sync>;
-pub type AsyncWidgetFn<W> = Box<dyn FnBox(Stale, WidgetCore)
- -> HResult<W> + Send + Sync>;
-
-
-type WidgetO = Box<dyn Widget + Send>;
+pub type AsyncWidgetFn<W> = FnOnce(&Stale, WidgetCore)
+ -> HResult<W> + Send + Sync;
lazy_static! {
static ref SUBPROC: Arc<Mutex<Option<u32>>> = { Arc::new(Mutex::new(None)) };
@@ -35,232 +28,9 @@ fn kill_proc() -> HResult<()> {
Ok(())
}
-#[derive(Clone, Debug)]
-pub struct Stale(Arc<RwLock<bool>>);
-impl Stale {
- pub fn new() -> Stale {
- Stale(Arc::new(RwLock::new(false)))
- }
- pub fn is_stale(&self) -> HResult<bool> {
- Ok(*self.0.read()?)
- }
- pub fn set_stale(&self) -> HResult<()> {
- *self.0.write()? = true;
- Ok(())
- }
- pub fn set_fresh(&self) -> HResult<()> {
- *self.0.write()? = false;
- Ok(())
- }
-}
-
-pub fn is_stale(stale: &Stale) -> HResult<bool> {
- let stale = stale.is_stale()?;
- Ok(stale)
-}
-
-use std::fmt::{Debug, Formatter};
-
-impl<T: Send + Debug> Debug for Async<T> {
- fn fmt(&self, formatter: &mut Formatter) -> Result<(), std::fmt::Error> {
- write!(formatter,
- "{:?}, {:?} {:?}",
- self.value,
- self.async_value,
- self.stale)
- }
-}
-
-
-#[derive(Clone)]
-pub struct Async<T: Send> {
- pub value: HResult<T>,
- async_value: AsyncValue<T>,
- async_closure: Arc<Mutex<Option<AsyncValueFn<T>>>>,
- on_ready: Arc<Mutex<Option<AsyncReadyFn>>>,
- started: bool,
- stale: Stale,
-}
-
-
-
-impl<T: Send + 'static> Async<T> {
- pub fn new(closure: AsyncValueFn<T>)
- -> Async<T> {
- let async_value = Async {
- value: HError::async_not_ready(),
- async_value: Arc::new(Mutex::new(None)),
- async_closure: Arc::new(Mutex::new(Some(closure))),
- on_ready: Arc::new(Mutex::new(None)),
- started: false,
- stale: Stale::new() };
-
- async_value
- }
-
- pub fn new_with_stale(closure: AsyncValueFn<T>,
- stale: Stale)
- -> Async<T> {
- let async_value = Async {
- value: HError::async_not_ready(),
- async_value: Arc::new(Mutex::new(None)),
- async_closure: Arc::new(Mutex::new(Some(closure))),
- on_ready: Arc::new(Mutex::new(None)),
- started: false,
- stale: stale };
-
- async_value
- }
-
- pub fn new_with_value(val: T) -> Async<T> {
- Async {
- value: Ok(val),
- async_value: Arc::new(Mutex::new(None)),
- async_closure: Arc::new(Mutex::new(None)),
- on_ready: Arc::new(Mutex::new(None)),
- started: false,
- stale: Stale::new()
- }
- }
-
- pub fn run_async(async_fn: Arc<Mutex<Option<AsyncValueFn<T>>>>,
- async_value: AsyncValue<T>,
- on_ready_fn: Arc<Mutex<Option<AsyncReadyFn>>>,
- stale: Stale) -> HResult<()> {
- let value_fn = async_fn.lock()?.take()?;
- let value = value_fn.call_box((stale.clone(),));
- async_value.lock()?.replace(value);
- on_ready_fn.lock()?
- .take()
- .map(|on_ready| on_ready.call_box(()).log());
- Ok(())
- }
-
- pub fn run(&mut self) -> HResult<()> {
- if self.started {
- HError::async_started()?
- }
-
- let closure = self.async_closure.clone();
- let async_value = self.async_value.clone();
- let stale = self.stale.clone();
- let on_ready_fn = self.on_ready.clone();
- self.started = true;
-
- std::thread::spawn(move || {
- Async::run_async(closure,
- async_value,
- on_ready_fn,
- stale).log();
- });
- Ok(())
- }
-
- pub fn run_pooled(&mut self, pool: &ThreadPool) -> HResult<()> {
- if self.started {
- HError::async_started()?
- }
-
- let closure = self.async_closure.clone();
- let async_value = self.async_value.clone();
- let stale = self.stale.clone();
- let on_ready_fn = self.on_ready.clone();
- self.started = true;
-
- pool.spawn(move || {
- Async::run_async(closure,
- async_value,
- on_ready_fn,
- stale).log();
- });
-
- Ok(())
- }
-
-
- pub fn wait(self) -> HResult<T> {
- Async::run_async(self.async_closure,
- self.async_value.clone(),
- self.on_ready,
- self.stale).log();
- let value = self.async_value.lock()?.take()?;
- value
- }
-
- pub fn set_s