Return UID validity

This commit is contained in:
Quentin 2022-06-23 14:41:10 +02:00
parent cea27474f9
commit 8a0df56cde
Signed by: quentin
GPG key ID: E9602264D639FF68
3 changed files with 35 additions and 12 deletions

View file

@ -83,6 +83,18 @@ impl<'a> StateContext<'a> {
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed S: A142 OK [READ-WRITE] SELECT completed
--- a mailbox with no unseen message -> no unseen entry
20 select "INBOX.achats"
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded JUNK $label1)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded JUNK $label1 \*)] Flags permitted.
* 88 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1347986788] UIDs valid
* OK [UIDNEXT 91] Predicted next UID
* OK [HIGHESTMODSEQ 72] Highest
20 OK [READ-WRITE] Select completed (0.001 + 0.000 secs).
* TRACE END --- * TRACE END ---
*/ */
async fn select(&self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> { async fn select(&self, mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> {
@ -96,8 +108,6 @@ impl<'a> StateContext<'a> {
let body = vec![Data::Exists(sum.exists.try_into()?), Data::Recent(0)]; let body = vec![Data::Exists(sum.exists.try_into()?), Data::Recent(0)];
let tr = flow::Transition::Select(mb);
let r_unseen = Status::ok( let r_unseen = Status::ok(
None, None,
Some(Code::Unseen( Some(Code::Unseen(
@ -108,13 +118,22 @@ impl<'a> StateContext<'a> {
.map_err(Error::msg)?; .map_err(Error::msg)?;
//let r_permanentflags = Status::ok(None, Some(Code:: //let r_permanentflags = Status::ok(None, Some(Code::
let tr = flow::Transition::Select(mb);
Ok(( Ok((
vec![ vec![
ImapRes::Data(Data::Exists(0)), ImapRes::Data(Data::Exists(0)),
ImapRes::Data(Data::Recent(0)), ImapRes::Data(Data::Recent(0)),
ImapRes::Data(Data::Flags(vec![])), ImapRes::Data(Data::Flags(vec![])),
ImapRes::Status(
Status::ok(
None,
Some(Code::UidValidity(sum.validity)),
"UIDs valid"
)
.map_err(Error::msg)?,
),
/*ImapRes::Status(), /*ImapRes::Status(),
ImapRes::Status(),
ImapRes::Status(),*/ ImapRes::Status(),*/
ImapRes::Status( ImapRes::Status(
Status::ok( Status::ok(

View file

@ -104,7 +104,7 @@ fn dump(uid_index: &Bayou<UidIndex>) {
"{} {} {}", "{} {} {}",
uid, uid,
hex::encode(ident.0), hex::encode(ident.0),
s.table.get(ident).cloned().unwrap_or_default().1.join(", ") s.table.get(ident).cloned().unwrap().1.join(", ")
); );
} }
println!(""); println!("");

View file

@ -1,11 +1,13 @@
use std::num::NonZeroU32;
use im::{HashMap, HashSet, OrdMap, OrdSet}; use im::{HashMap, HashSet, OrdMap, OrdSet};
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use crate::bayou::*; use crate::bayou::*;
use crate::mail_ident::MailIdent; use crate::mail_ident::MailIdent;
pub type ImapUid = u32; pub type ImapUid = NonZeroU32;
pub type ImapUidvalidity = u32; pub type ImapUidvalidity = NonZeroU32;
pub type Flag = String; pub type Flag = String;
#[derive(Clone)] #[derive(Clone)]
@ -90,9 +92,9 @@ impl Default for UidIndex {
table: OrdMap::new(), table: OrdMap::new(),
idx_by_uid: OrdMap::new(), idx_by_uid: OrdMap::new(),
idx_by_flag: FlagIndex::new(), idx_by_flag: FlagIndex::new(),
uidvalidity: 1, uidvalidity: NonZeroU32::new(1).unwrap(),
uidnext: 1, uidnext: NonZeroU32::new(1).unwrap(),
internalseq: 1, internalseq: NonZeroU32::new(1).unwrap(),
} }
} }
} }
@ -106,7 +108,9 @@ impl BayouState for UidIndex {
UidIndexOp::MailAdd(ident, uid, flags) => { UidIndexOp::MailAdd(ident, uid, flags) => {
// Change UIDValidity if there is a conflict // Change UIDValidity if there is a conflict
if *uid < new.internalseq { if *uid < new.internalseq {
new.uidvalidity += new.internalseq - *uid; new.uidvalidity =
NonZeroU32::new(new.uidvalidity.get() + new.internalseq.get() - uid.get())
.unwrap();
} }
// Assign the real uid of the email // Assign the real uid of the email
@ -123,7 +127,7 @@ impl BayouState for UidIndex {
new.reg_email(*ident, new_uid, flags); new.reg_email(*ident, new_uid, flags);
// Update counters // Update counters
new.internalseq += 1; new.internalseq = NonZeroU32::new(new.internalseq.get() + 1).unwrap();
new.uidnext = new.internalseq; new.uidnext = new.internalseq;
} }
UidIndexOp::MailDel(ident) => { UidIndexOp::MailDel(ident) => {
@ -131,7 +135,7 @@ impl BayouState for UidIndex {
new.unreg_email(ident); new.unreg_email(ident);
// We update the counter // We update the counter
new.internalseq += 1; new.internalseq = NonZeroU32::new(new.internalseq.get() + 1).unwrap();
} }
UidIndexOp::FlagAdd(ident, new_flags) => { UidIndexOp::FlagAdd(ident, new_flags) => {
if let Some((uid, existing_flags)) = new.table.get_mut(ident) { if let Some((uid, existing_flags)) = new.table.get_mut(ident) {