aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/imap/command/authenticated.rs25
-rw-r--r--src/mailbox.rs2
-rw-r--r--src/uidindex.rs20
3 files changed, 35 insertions, 12 deletions
diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs
index fca15fc..378564b 100644
--- a/src/imap/command/authenticated.rs
+++ b/src/imap/command/authenticated.rs
@@ -83,6 +83,18 @@ impl<'a> StateContext<'a> {
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
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 ---
*/
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 tr = flow::Transition::Select(mb);
-
let r_unseen = Status::ok(
None,
Some(Code::Unseen(
@@ -108,13 +118,22 @@ impl<'a> StateContext<'a> {
.map_err(Error::msg)?;
//let r_permanentflags = Status::ok(None, Some(Code::
+ let tr = flow::Transition::Select(mb);
+
Ok((
vec![
ImapRes::Data(Data::Exists(0)),
ImapRes::Data(Data::Recent(0)),
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(
Status::ok(
diff --git a/src/mailbox.rs b/src/mailbox.rs
index 249d329..54c22e3 100644
--- a/src/mailbox.rs
+++ b/src/mailbox.rs
@@ -104,7 +104,7 @@ fn dump(uid_index: &Bayou<UidIndex>) {
"{} {} {}",
uid,
hex::encode(ident.0),
- s.table.get(ident).cloned().unwrap_or_default().1.join(", ")
+ s.table.get(ident).cloned().unwrap().1.join(", ")
);
}
println!("");
diff --git a/src/uidindex.rs b/src/uidindex.rs
index 8e4a189..f53d770 100644
--- a/src/uidindex.rs
+++ b/src/uidindex.rs
@@ -1,11 +1,13 @@
+use std::num::NonZeroU32;
+
use im::{HashMap, HashSet, OrdMap, OrdSet};
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use crate::bayou::*;
use crate::mail_ident::MailIdent;
-pub type ImapUid = u32;
-pub type ImapUidvalidity = u32;
+pub type ImapUid = NonZeroU32;
+pub type ImapUidvalidity = NonZeroU32;
pub type Flag = String;
#[derive(Clone)]
@@ -90,9 +92,9 @@ impl Default for UidIndex {
table: OrdMap::new(),
idx_by_uid: OrdMap::new(),
idx_by_flag: FlagIndex::new(),
- uidvalidity: 1,
- uidnext: 1,
- internalseq: 1,
+ uidvalidity: NonZeroU32::new(1).unwrap(),
+ uidnext: NonZeroU32::new(1).unwrap(),
+ internalseq: NonZeroU32::new(1).unwrap(),
}
}
}
@@ -106,7 +108,9 @@ impl BayouState for UidIndex {
UidIndexOp::MailAdd(ident, uid, flags) => {
// Change UIDValidity if there is a conflict
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
@@ -123,7 +127,7 @@ impl BayouState for UidIndex {
new.reg_email(*ident, new_uid, flags);
// Update counters
- new.internalseq += 1;
+ new.internalseq = NonZeroU32::new(new.internalseq.get() + 1).unwrap();
new.uidnext = new.internalseq;
}
UidIndexOp::MailDel(ident) => {
@@ -131,7 +135,7 @@ impl BayouState for UidIndex {
new.unreg_email(ident);
// We update the counter
- new.internalseq += 1;
+ new.internalseq = NonZeroU32::new(new.internalseq.get() + 1).unwrap();
}
UidIndexOp::FlagAdd(ident, new_flags) => {
if let Some((uid, existing_flags)) = new.table.get_mut(ident) {