Rename MailUuid in MailIdent
This commit is contained in:
parent
13ed1b3890
commit
da6881199c
2 changed files with 51 additions and 42 deletions
|
@ -69,7 +69,7 @@ impl Mailbox {
|
|||
let add_mail_op = self
|
||||
.uid_index
|
||||
.state()
|
||||
.op_mail_add(MailUuid(rand_id), vec!["\\Unseen".into()]);
|
||||
.op_mail_add(MailIdent(rand_id), vec!["\\Unseen".into()]);
|
||||
self.uid_index.push(add_mail_op).await?;
|
||||
|
||||
dump(&self.uid_index);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use im::{HashMap, HashSet, OrdMap};
|
||||
use im::{HashMap, HashSet, OrdSet, OrdMap};
|
||||
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::bayou::*;
|
||||
|
@ -7,11 +7,15 @@ pub type ImapUid = u32;
|
|||
pub type ImapUidvalidity = u32;
|
||||
pub type Flag = String;
|
||||
|
||||
/// A Mail UUID is composed of two components:
|
||||
/// Mail Identifier (MailIdent) are composed of two components:
|
||||
/// - a process identifier, 128 bits
|
||||
/// - a sequence number, 64 bits
|
||||
/// They are not part of the protocol but an internal representation
|
||||
/// required by Mailrage/Aerogramme.
|
||||
/// Their main property is to be unique without having to rely
|
||||
/// on synchronization between IMAP processes.
|
||||
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct MailUuid(pub [u8; 24]);
|
||||
pub struct MailIdent(pub [u8; 24]);
|
||||
|
||||
#[derive(Clone)]
|
||||
/// A UidIndex handles the mutable part of a mailbox
|
||||
|
@ -20,10 +24,10 @@ pub struct MailUuid(pub [u8; 24]);
|
|||
/// and applying the event. This is why we use immutable datastructures
|
||||
/// that are optimized for cloning (they clone underlying values only if they are modified)
|
||||
pub struct UidIndex {
|
||||
pub mail_uid: OrdMap<MailUuid, ImapUid>,
|
||||
pub mail_flags: OrdMap<MailUuid, Vec<Flag>>,
|
||||
pub mails_by_uid: OrdMap<ImapUid, MailUuid>,
|
||||
pub flags: HashMap<Flag, HashSet<MailUuid>>,
|
||||
pub mail_uid: OrdMap<MailIdent, ImapUid>,
|
||||
pub mail_flags: OrdMap<MailIdent, Vec<Flag>>,
|
||||
pub mails_by_uid: OrdMap<ImapUid, MailIdent>,
|
||||
pub flags: HashMap<Flag, OrdSet<ImapUid>>,
|
||||
|
||||
pub uidvalidity: ImapUidvalidity,
|
||||
pub uidnext: ImapUid,
|
||||
|
@ -32,31 +36,31 @@ pub struct UidIndex {
|
|||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum UidIndexOp {
|
||||
MailAdd(MailUuid, ImapUid, Vec<Flag>),
|
||||
MailDel(MailUuid),
|
||||
FlagAdd(MailUuid, Vec<Flag>),
|
||||
FlagDel(MailUuid, Vec<Flag>),
|
||||
MailAdd(MailIdent, ImapUid, Vec<Flag>),
|
||||
MailDel(MailIdent),
|
||||
FlagAdd(MailIdent, Vec<Flag>),
|
||||
FlagDel(MailIdent, Vec<Flag>),
|
||||
}
|
||||
|
||||
impl UidIndex {
|
||||
#[must_use]
|
||||
pub fn op_mail_add(&self, uuid: MailUuid, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::MailAdd(uuid, self.internalseq, flags)
|
||||
pub fn op_mail_add(&self, ident: MailIdent, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::MailAdd(ident, self.internalseq, flags)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn op_mail_del(&self, uuid: MailUuid) -> UidIndexOp {
|
||||
UidIndexOp::MailDel(uuid)
|
||||
pub fn op_mail_del(&self, ident: MailIdent) -> UidIndexOp {
|
||||
UidIndexOp::MailDel(ident)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn op_flag_add(&self, uuid: MailUuid, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::FlagAdd(uuid, flags)
|
||||
pub fn op_flag_add(&self, ident: MailIdent, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::FlagAdd(ident, flags)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn op_flag_del(&self, uuid: MailUuid, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::FlagDel(uuid, flags)
|
||||
pub fn op_flag_del(&self, ident: MailIdent, flags: Vec<Flag>) -> UidIndexOp {
|
||||
UidIndexOp::FlagDel(ident, flags)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,60 +84,65 @@ impl BayouState for UidIndex {
|
|||
fn apply(&self, op: &UidIndexOp) -> Self {
|
||||
let mut new = self.clone();
|
||||
match op {
|
||||
UidIndexOp::MailAdd(uuid, uid, flags) => {
|
||||
UidIndexOp::MailAdd(ident, uid, flags) => {
|
||||
// Change UIDValidity if there is a conflict
|
||||
if *uid < new.internalseq {
|
||||
new.uidvalidity += new.internalseq - *uid;
|
||||
}
|
||||
|
||||
// Assign the real uid
|
||||
let new_uid = new.internalseq;
|
||||
|
||||
if let Some(prev_uid) = new.mail_uid.get(uuid) {
|
||||
if let Some(prev_uid) = new.mail_uid.get(ident) {
|
||||
new.mails_by_uid.remove(prev_uid);
|
||||
} else {
|
||||
new.mail_flags.insert(*uuid, flags.clone());
|
||||
new.mail_flags.insert(*ident, flags.clone());
|
||||
}
|
||||
new.mails_by_uid.insert(new_uid, *uuid);
|
||||
new.mail_uid.insert(*uuid, new_uid);
|
||||
new.mails_by_uid.insert(new_uid, *ident);
|
||||
new.mail_uid.insert(*ident, new_uid);
|
||||
|
||||
new.internalseq += 1;
|
||||
new.uidnext = new.internalseq;
|
||||
}
|
||||
UidIndexOp::MailDel(uuid) => {
|
||||
if let Some(uid) = new.mail_uid.get(uuid) {
|
||||
UidIndexOp::MailDel(ident) => {
|
||||
if let Some(uid) = new.mail_uid.get(ident) {
|
||||
new.mails_by_uid.remove(uid);
|
||||
new.mail_uid.remove(uuid);
|
||||
new.mail_flags.remove(uuid);
|
||||
new.mail_uid.remove(ident);
|
||||
new.mail_flags.remove(ident);
|
||||
}
|
||||
new.internalseq += 1;
|
||||
}
|
||||
UidIndexOp::FlagAdd(uuid, new_flags) => {
|
||||
UidIndexOp::FlagAdd(ident, new_flags) => {
|
||||
// Upate mapping Email -> Flag
|
||||
let mail_flags = new.mail_flags.entry(*uuid).or_insert(vec![]);
|
||||
let mail_flags = new.mail_flags.entry(*ident).or_insert(vec![]);
|
||||
for flag in new_flags {
|
||||
if !mail_flags.contains(flag) {
|
||||
mail_flags.push(flag.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Update mapping Flag -> Email
|
||||
// Update mapping Flag -> ImapUid
|
||||
|
||||
/*
|
||||
let _ = new_flags.iter().map(|flag| {
|
||||
new.flags
|
||||
.entry(flag.clone())
|
||||
.or_insert(HashSet::new())
|
||||
.or_insert(OrdSet::new())
|
||||
.update(*uuid)
|
||||
});
|
||||
});*/
|
||||
}
|
||||
UidIndexOp::FlagDel(uuid, rm_flags) => {
|
||||
UidIndexOp::FlagDel(ident, rm_flags) => {
|
||||
// Upate mapping Email -> Flag
|
||||
if let Some(mail_flags) = new.mail_flags.get_mut(uuid) {
|
||||
if let Some(mail_flags) = new.mail_flags.get_mut(ident) {
|
||||
mail_flags.retain(|x| !rm_flags.contains(x));
|
||||
}
|
||||
|
||||
// Update mapping Flag -> Email
|
||||
rm_flags.iter().for_each(|flag| {
|
||||
// Update mapping Flag -> ImapUid
|
||||
/*rm_flags.iter().for_each(|flag| {
|
||||
new.flags
|
||||
.entry(flag.clone())
|
||||
.and_modify(|hs| { hs.remove(uuid); });
|
||||
});
|
||||
});*/
|
||||
}
|
||||
}
|
||||
new
|
||||
|
@ -144,7 +153,7 @@ impl BayouState for UidIndex {
|
|||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct UidIndexSerializedRepr {
|
||||
mails: Vec<(ImapUid, MailUuid, Vec<Flag>)>,
|
||||
mails: Vec<(ImapUid, MailIdent, Vec<Flag>)>,
|
||||
uidvalidity: ImapUidvalidity,
|
||||
uidnext: ImapUid,
|
||||
internalseq: ImapUid,
|
||||
|
@ -202,7 +211,7 @@ impl Serialize for UidIndex {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for MailUuid {
|
||||
impl<'de> Deserialize<'de> for MailIdent {
|
||||
fn deserialize<D>(d: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
|
@ -220,7 +229,7 @@ impl<'de> Deserialize<'de> for MailUuid {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serialize for MailUuid {
|
||||
impl Serialize for MailIdent {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
|
|
Loading…
Reference in a new issue