Skip to content

Commit

Permalink
Fetch now support the MODSEQ data item
Browse files Browse the repository at this point in the history
  • Loading branch information
superboum committed Jan 10, 2024
1 parent eb37f06 commit 990e709
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
15 changes: 14 additions & 1 deletion imap-codec/src/codec/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
//! C: Pa²²W0rD
//! ```
use std::{borrow::Borrow, io::Write, num::NonZeroU32};
use std::{borrow::Borrow, io::Write, num::{NonZeroU32, NonZeroU64}};

use base64::{engine::general_purpose::STANDARD as base64, Engine};
use chrono::{DateTime as ChronoDateTime, FixedOffset};
Expand Down Expand Up @@ -980,6 +980,7 @@ impl<'a> EncodeIntoContext for MessageDataItemName<'a> {
Self::Rfc822Size => ctx.write_all(b"RFC822.SIZE"),
Self::Rfc822Text => ctx.write_all(b"RFC822.TEXT"),
Self::Uid => ctx.write_all(b"UID"),
Self::ModSeq => ctx.write_all(b"MODSEQ"),
}
}
}
Expand Down Expand Up @@ -1044,6 +1045,12 @@ impl EncodeIntoContext for NonZeroU32 {
}
}

impl EncodeIntoContext for NonZeroU64 {
fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
write!(ctx, "{self}")
}
}

impl<'a> EncodeIntoContext for Capability<'a> {
fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
write!(ctx, "{}", self)
Expand Down Expand Up @@ -1295,6 +1302,7 @@ impl<'a> EncodeIntoContext for Data<'a> {
root.encode_ctx(ctx)?;
}
}

#[cfg(feature = "ext_id")]
Data::Id { parameters } => {
ctx.write_all(b"* ID ")?;
Expand Down Expand Up @@ -1448,6 +1456,11 @@ impl<'a> EncodeIntoContext for MessageDataItem<'a> {
nstring.encode_ctx(ctx)
}
Self::Uid(uid) => write!(ctx, "UID {uid}"),
Self::ModSeq(modseq) => {
ctx.write_all(b"MODSEQ (")?;
modseq.encode_ctx(ctx)?;
ctx.write_all(b")")
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion imap-codec/src/core.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Cow, num::NonZeroU32, str::from_utf8};
use std::{borrow::Cow, num::{NonZeroU32, NonZeroU64}, str::from_utf8};

#[cfg(not(feature = "quirk_crlf_relaxed"))]
use abnf_core::streaming::crlf;
Expand Down Expand Up @@ -65,6 +65,10 @@ pub(crate) fn nz_number(input: &[u8]) -> IMAPResult<&[u8], NonZeroU32> {
map_res(number, NonZeroU32::try_from)(input)
}

pub(crate) fn nz_number64(input: &[u8]) -> IMAPResult<&[u8], NonZeroU64> {
map_res(number64, NonZeroU64::try_from)(input)
}

// ----- string -----

/// `string = quoted / literal`
Expand Down
8 changes: 6 additions & 2 deletions imap-codec/src/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::num::NonZeroU32;
use std::num::{NonZeroU32};

use abnf_core::streaming::sp;
use imap_types::{
Expand All @@ -15,7 +15,7 @@ use nom::{

use crate::{
body::body,
core::{astring, nstring, number, nz_number},
core::{astring, nstring, number, nz_number64, nz_number},
datetime::date_time,
decode::IMAPResult,
envelope::envelope,
Expand Down Expand Up @@ -83,6 +83,7 @@ pub(crate) fn fetch_att(input: &[u8]) -> IMAPResult<&[u8], MessageDataItemName>
value(MessageDataItemName::Rfc822Size, tag_no_case(b"RFC822.SIZE")),
value(MessageDataItemName::Rfc822Text, tag_no_case(b"RFC822.TEXT")),
value(MessageDataItemName::Rfc822, tag_no_case(b"RFC822")),
value(MessageDataItemName::ModSeq, tag_no_case(b"MODSEQ")),
))(input)
}

Expand Down Expand Up @@ -175,6 +176,9 @@ pub(crate) fn msg_att_static(input: &[u8]) -> IMAPResult<&[u8], MessageDataItem>
map(tuple((tag_no_case(b"UID"), sp, uniqueid)), |(_, _, uid)| {
MessageDataItem::Uid(uid)
}),
map(tuple((tag_no_case(b"MODSEQ "), delimited(tag("("), nz_number64, tag(")")))), |(_, modseq)| {
MessageDataItem::ModSeq(modseq)
}),
))(input)
}

Expand Down
8 changes: 7 additions & 1 deletion imap-types/src/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{
fmt::{Display, Formatter},
num::NonZeroU32,
num::{NonZeroU32, NonZeroU64},
};

#[cfg(feature = "arbitrary")]
Expand Down Expand Up @@ -229,6 +229,9 @@ pub enum MessageDataItemName<'a> {
/// UID
/// ```
Uid,

/// The ModSeq of CONDSTORE
ModSeq,
}

/// Message data item.
Expand Down Expand Up @@ -356,6 +359,9 @@ pub enum MessageDataItem<'a> {
/// UID
/// ```
Uid(NonZeroU32),

/// The ModSeq value described in CONDSTORE
ModSeq(NonZeroU64),
}

/// A part specifier is either a part number or one of the following:
Expand Down

0 comments on commit 990e709

Please sign in to comment.