diff --git a/.gitignore b/.gitignore index ea8c4bf..9649e79 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.vimrc 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 Bayou { }) } + /// 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), MailDel(MailUuid), + FlagAdd(MailUuid, Vec), + FlagDel(MailUuid, Vec), +} + +impl UidIndex { + #[must_use] + pub fn op_mail_add(&self, uuid: MailUuid, flags: Vec) -> 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) -> UidIndexOp { + UidIndexOp::FlagAdd(uuid, flags) + } + + #[must_use] + pub fn op_flag_del(&self, uuid: MailUuid, flags: Vec) -> 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 }