aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bayou.rs15
-rw-r--r--src/main.rs9
-rw-r--r--src/uidindex.rs37
3 files changed, 57 insertions, 4 deletions
diff --git a/src/bayou.rs b/src/bayou.rs
index 8fc711e..1ea8395 100644
--- a/src/bayou.rs
+++ b/src/bayou.rs
@@ -62,18 +62,29 @@ impl<S: BayouState> Bayou<S> {
})
}
+ /// Re-reads the state from persistent storage backend
pub async fn sync(&mut self) -> Result<()> {
// 1. List checkpoints
- // 2. Load last checkpoint
+ // 2. Load last checkpoint if different from currently used one
// 3. List all operations starting from checkpoint
// 4. Check that first operation has same timestamp as checkpoint (if not zero)
// 5. Apply all operations in order
unimplemented!()
}
- pub fn state(&self) -> &S {
+ /// Applies a new operation on the state. Once this function returns,
+ /// the option has been safely persisted to storage backend
+ pub async fn push(&mut self, op: S::Op) -> Result<()> {
unimplemented!()
}
+
+ pub fn state(&self) -> &S {
+ if let Some(last) = self.history.last() {
+ last.2.as_ref().unwrap()
+ } else {
+ &self.checkpoint.1
+ }
+ }
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
diff --git a/src/main.rs b/src/main.rs
index 2b17e4c..81cf220 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,9 +8,9 @@ mod cryptoblob;
mod time;
mod uidindex;
-use bayou::Bayou;
+use bayou::*;
use cryptoblob::Key;
-use uidindex::{UidIndex, UidIndexOp};
+use uidindex::*;
#[tokio::main]
async fn main() {
@@ -43,5 +43,10 @@ async fn do_stuff() -> Result<()> {
mail_index.sync().await?;
+ let add_mail_op = mail_index
+ .state()
+ .op_mail_add(MailUuid([0xFFu8; 24]), vec!["\\Unseen".into()]);
+ mail_index.push(add_mail_op).await?;
+
Ok(())
}
diff --git a/src/uidindex.rs b/src/uidindex.rs
index 7c5500f..600cf6a 100644
--- a/src/uidindex.rs
+++ b/src/uidindex.rs
@@ -28,6 +28,30 @@ pub struct UidIndex {
pub enum UidIndexOp {
MailAdd(MailUuid, ImapUid, Vec<String>),
MailDel(MailUuid),
+ FlagAdd(MailUuid, Vec<String>),
+ FlagDel(MailUuid, Vec<String>),
+}
+
+impl UidIndex {
+ #[must_use]
+ pub fn op_mail_add(&self, uuid: MailUuid, flags: Vec<String>) -> UidIndexOp {
+ UidIndexOp::MailAdd(uuid, self.internalseq, flags)
+ }
+
+ #[must_use]
+ pub fn op_mail_del(&self, uuid: MailUuid) -> UidIndexOp {
+ UidIndexOp::MailDel(uuid)
+ }
+
+ #[must_use]
+ pub fn op_flag_add(&self, uuid: MailUuid, flags: Vec<String>) -> UidIndexOp {
+ UidIndexOp::FlagAdd(uuid, flags)
+ }
+
+ #[must_use]
+ pub fn op_flag_del(&self, uuid: MailUuid, flags: Vec<String>) -> UidIndexOp {
+ UidIndexOp::FlagDel(uuid, flags)
+ }
}
impl Default for UidIndex {
@@ -74,6 +98,19 @@ impl BayouState for UidIndex {
}
new.internalseq += 1;
}
+ UidIndexOp::FlagAdd(uuid, new_flags) => {
+ let mail_flags = new.mail_flags.entry(*uuid).or_insert(vec![]);
+ for flag in new_flags {
+ if !mail_flags.contains(flag) {
+ mail_flags.push(flag.to_string());
+ }
+ }
+ }
+ UidIndexOp::FlagDel(uuid, rm_flags) => {
+ if let Some(mail_flags) = new.mail_flags.get_mut(uuid) {
+ mail_flags.retain(|x| !rm_flags.contains(x));
+ }
+ }
}
new
}