summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml3
-rw-r--r--src/mailcache.rs88
-rw-r--r--src/mailstore.rs5
-rw-r--r--src/main.rs1
4 files changed, 97 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 66fe450..f04bf9c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,4 +18,7 @@ cursive = "0.15"
git = "https://github.com/matthiasbeyer/cursive_tree_view"
branch = "update-deps"
+[dependencies.async-std]
+version = "1.6"
+features = ["unstable"]
diff --git a/src/mailcache.rs b/src/mailcache.rs
new file mode 100644
index 0000000..1bb8f6f
--- /dev/null
+++ b/src/mailcache.rs
@@ -0,0 +1,88 @@
+use std::path::PathBuf;
+use std::path::Path;
+use std::sync::Arc;
+use std::sync::RwLock;
+use anyhow::Result;
+use anyhow::Error;
+use async_std::sync::{Sender, Receiver};
+use async_std::sync::TryRecvError;
+use async_std::sync::channel;
+use async_std::task;
+
+use crate::mailstore::MailStore;
+
+struct Cache {
+ cache: Vec<MailStore>,
+ receiver: Receiver<Result<MailStore>>,
+}
+
+impl Cache {
+ fn find(&self, path: &Path) -> Option<&MailStore> {
+ self.cache.iter().find(|e| e.path() == path)
+ }
+
+ fn update(&mut self) -> Result<()> {
+ loop {
+ match self.receiver.try_recv() {
+ Ok(queued) => {
+ self.cache.push(queued?);
+ }
+ Err(TryRecvError::Empty) => break,
+ Err(other) => {
+ return Err(other).map_err(Error::from)
+ },
+ }
+ }
+
+ Ok(())
+ }
+}
+
+#[derive(Clone)]
+pub struct MailCache {
+ cache: Arc<RwLock<Cache>>,
+ sender: Sender<Result<MailStore>>,
+}
+
+impl MailCache {
+
+ pub fn new(buffer_cap: usize) -> Self {
+ let (s, r) = channel(buffer_cap);
+ MailCache {
+ cache: Arc::new(RwLock::new(Cache {
+ cache: Vec::new(),
+ receiver: r,
+ })),
+ sender: s
+ }
+ }
+
+ pub fn load_background(&self, path: PathBuf) {
+ let sender = self.sender.clone();
+ task::spawn(async move {
+ let mut ms = MailStore::from_path(path);
+ let r = ms.load().map(|_| ms);
+
+ sender.send(r).await
+ });
+ }
+
+ pub fn exec_on<F, T>(&self, path: &Path, f: F) -> Result<T>
+ where T: Sized,
+ F: FnOnce(Option<&MailStore>) -> Result<T>,
+ {
+ self.cache
+ .read()
+ .map_err(|_| anyhow!("RWLock possibly poisened"))
+ .and_then(|cache| f(cache.find(path)))
+ }
+
+ pub fn update_cache(&mut self) -> Result<()> {
+ self.cache
+ .write()
+ .map_err(|_| anyhow!("Possibly poisened RWLock"))
+ .and_then(|mut cache| cache.update())
+ }
+
+}
+
diff --git a/src/mailstore.rs b/src/mailstore.rs
index 3f1d299..cbb59fd 100644
--- a/src/mailstore.rs
+++ b/src/mailstore.rs
@@ -1,4 +1,5 @@
use std::path::PathBuf;
+use std::path::Path;
use anyhow::Error;
use anyhow::Result;
use maildir::Maildir;
@@ -33,6 +34,10 @@ impl MailStore {
pub fn cur_mail(&self) -> &Vec<Mail> {
&self.cur
}
+
+ pub fn path(&self) -> &Path {
+ self.dir.path()
+ }
}
pub struct Mail {
diff --git a/src/main.rs b/src/main.rs
index 04f041d..232f834 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,6 +7,7 @@ use mailparse::MailHeaderMap;
use mailparse::ParsedMail;
mod mailstore;
+mod mailcache;
mod sidebar;
mod main_view;