diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2020-07-07 17:53:47 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2020-07-07 17:53:47 +0200 |
commit | 8eadd57a6a6ec1c9a8618ded99ad1869dc84c841 (patch) | |
tree | 7010ba427606f5f7adbb9b341b079c3e7419c3e1 /src | |
parent | 757e22b8a78b994431a32114280f7752e4705f74 (diff) |
Refactor AsyncView creation into Loader / PostProcessor abstraction
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/loader.rs | 19 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/main_view.rs | 36 | ||||
-rw-r--r-- | src/sidebar.rs | 13 |
4 files changed, 53 insertions, 16 deletions
diff --git a/src/loader.rs b/src/loader.rs new file mode 100644 index 0000000..2a2d573 --- /dev/null +++ b/src/loader.rs @@ -0,0 +1,19 @@ +/// Helper trait to load something and then postprocess it +/// +/// the load() function might fail, but the PostProcessor::postprocess() function should never fail. +pub trait Loader { + type Output: Sized; + type Error: Sized; + type PostProcessedOutput: Sized; + type PostProcessor: PostProcessor<Self::Output, Output = Self::PostProcessedOutput>; + + fn load(self) -> Result<Self::Output, Self::Error>; + fn postprocessor(&self) -> Self::PostProcessor; +} + +pub trait PostProcessor<Object: Sized> { + type Output: Sized; + + fn postprocess(&self, o: Object) -> Self::Output; +} + diff --git a/src/main.rs b/src/main.rs index 26f9a47..174fd71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use env_logger::Env; mod mailstore; mod sidebar; mod main_view; +mod loader; mod util; fn main() -> Result<()> { diff --git a/src/main_view.rs b/src/main_view.rs index 9048fb2..6f45296 100644 --- a/src/main_view.rs +++ b/src/main_view.rs @@ -11,6 +11,8 @@ use mailparse::ParsedMail; use async_std::sync::channel; use crate::mailstore::{ MailStore, Mail }; +use crate::loader::Loader; +use crate::loader::PostProcessor; pub const MAIN_VIEW_NAME: &'static str = "main_view"; @@ -69,11 +71,10 @@ impl MainView { MainView { tabs }.with_name(MAIN_VIEW_NAME) } - pub fn maildir_loader(&mut self, pb: PathBuf) -> (MaildirLoader, MaildirLoaderPostProcessor) { + pub fn maildir_loader(&mut self, pb: PathBuf) -> MaildirLoader { debug!("Creating Loader for: {}", pb.display()); - let maildir_loader = MaildirLoader { maildir_path: pb }; - let postprocessor = MaildirLoaderPostProcessor; - (maildir_loader, postprocessor) + let maildir_loader = MaildirLoader(pb); + maildir_loader } pub fn add_tab<T: View>(&mut self, id: String, view: T) { @@ -82,14 +83,17 @@ impl MainView { } -pub struct MaildirLoader { - maildir_path: PathBuf -} +pub struct MaildirLoader(PathBuf); + +impl Loader for MaildirLoader { + type Output = Vec<String>; + type Error = String; + type PostProcessedOutput = cursive::views::ListView; + type PostProcessor = MaildirLoaderPostProcessor; -impl MaildirLoader { - pub fn load(self) -> RResult<Vec<String>, String> { - debug!("Loading: {}", self.maildir_path.display()); - MailStore::build_from_path(self.maildir_path).collect::<Result<MailStore>>() + fn load(self) -> Result<Self::Output, Self::Error> { + debug!("Loading: {}", self.0.display()); + MailStore::build_from_path(self.0).collect::<Result<MailStore>>() .map(|store| { store.cur_mail() .iter() @@ -107,11 +111,17 @@ impl MaildirLoader { }) .map_err(|e| e.to_string()) } + + fn postprocessor(&self) -> Self::PostProcessor { + MaildirLoaderPostProcessor + } } pub struct MaildirLoaderPostProcessor; -impl MaildirLoaderPostProcessor { - pub fn postprocess(&self, list: Vec<String>) -> cursive::views::ListView { +impl PostProcessor<Vec<String>> for MaildirLoaderPostProcessor { + type Output = cursive::views::ListView; + + fn postprocess(&self, list: Vec<String>) -> Self::Output{ list.into_iter() .fold(cursive::views::ListView::new(), |view, elem| { view.child("", cursive::views::TextView::new(elem)) diff --git a/src/sidebar.rs b/src/sidebar.rs index d0427d5..48b7a6a 100644 --- a/src/sidebar.rs +++ b/src/sidebar.rs @@ -9,6 +9,9 @@ use cursive::views::NamedView; use cursive_tree_view::TreeView; use crate::main_view::MainView; +use crate::main_view::MaildirLoader; +use crate::loader::PostProcessor; +use crate::loader::Loader; #[derive(Debug)] pub struct TreeEntry { @@ -54,7 +57,7 @@ impl Sidebar { .flatten(); if let Some(path) = borrow { - let (loader, processor) = { + let loader = { // Fetch the loader for the view to be created let p = path.clone(); siv.call_on_name(crate::main_view::MAIN_VIEW_NAME, move |main_view: &mut MainView| { Some(main_view.maildir_loader(p)) @@ -63,9 +66,12 @@ impl Sidebar { .unwrap() }; + let postprocessor = loader.postprocessor(); + + // Construct the AsyncView with the loader job let list_view = cursive_async_view::AsyncView::new_with_bg_creator(&mut siv, - move || { loader.load() }, - move |list| { processor.postprocess(list) }); + || { loader.load() }, + move |list| { postprocessor.postprocess(list) }); let name = path.file_name() .and_then(OsStr::to_str) @@ -73,6 +79,7 @@ impl Sidebar { .ok_or_else(|| anyhow!("UTF8 error")) .unwrap(); + // Add the AsyncView to the screen siv.call_on_name(crate::main_view::MAIN_VIEW_NAME, move |main_view: &mut MainView| { Some(main_view.add_tab(name, list_view)) }); |