aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-01-06 11:07:53 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-01-06 11:07:53 +0100
commita84ba4d42fcdb38be514178eb9fced777ba76055 (patch)
treea58b8e9b3528294b084c2eb2fe37f28128437bc8
parent4806f7ff84c595ec6647744577388fe4fab33736 (diff)
downloadaerogramme-a84ba4d42fcdb38be514178eb9fced777ba76055.tar.gz
aerogramme-a84ba4d42fcdb38be514178eb9fced777ba76055.zip
Mailbox View made more readable
-rw-r--r--src/imap/index.rs80
-rw-r--r--src/imap/mail_view.rs94
-rw-r--r--src/imap/mailbox_view.rs119
-rw-r--r--src/imap/mod.rs2
-rw-r--r--src/imap/selectors.rs100
-rw-r--r--src/mail/query.rs7
6 files changed, 143 insertions, 259 deletions
diff --git a/src/imap/index.rs b/src/imap/index.rs
new file mode 100644
index 0000000..347222c
--- /dev/null
+++ b/src/imap/index.rs
@@ -0,0 +1,80 @@
+use std::num::NonZeroU32;
+
+use anyhow::{anyhow, bail, Result};
+use imap_codec::imap_types::sequence::{self, SequenceSet};
+
+use crate::mail::uidindex::{ImapUid, UidIndex};
+use crate::mail::unique_ident::UniqueIdent;
+
+pub struct Index<'a>(pub &'a UidIndex);
+impl<'a> Index<'a> {
+ pub fn fetch(self: &Index<'a>, sequence_set: &SequenceSet, by_uid: bool) -> Result<Vec<MailIndex<'a>>> {
+ let mail_vec = self
+ .0
+ .idx_by_uid
+ .iter()
+ .map(|(uid, uuid)| (*uid, *uuid))
+ .collect::<Vec<_>>();
+
+ let mut mails = vec![];
+
+ if by_uid {
+ if mail_vec.is_empty() {
+ return Ok(vec![]);
+ }
+ let iter_strat = sequence::Strategy::Naive {
+ largest: mail_vec.last().unwrap().0,
+ };
+
+ let mut i = 0;
+ for uid in sequence_set.iter(iter_strat) {
+ while mail_vec.get(i).map(|mail| mail.0 < uid).unwrap_or(false) {
+ i += 1;
+ }
+ if let Some(mail) = mail_vec.get(i) {
+ if mail.0 == uid {
+ mails.push(MailIndex {
+ i: NonZeroU32::try_from(i as u32 + 1).unwrap(),
+ uid: mail.0,
+ uuid: mail.1,
+ flags: self.0.table.get(&mail.1).ok_or(anyhow!("mail is missing from index"))?.1.as_ref(),
+ });
+ }
+ } else {
+ break;
+ }
+ }
+ } else {
+ if mail_vec.is_empty() {
+ bail!("No such message (mailbox is empty)");
+ }
+
+ let iter_strat = sequence::Strategy::Naive {
+ largest: NonZeroU32::try_from((mail_vec.len()) as u32).unwrap(),
+ };
+
+ for i in sequence_set.iter(iter_strat) {
+ if let Some(mail) = mail_vec.get(i.get() as usize - 1) {
+ mails.push(MailIndex {
+ i,
+ uid: mail.0,
+ uuid: mail.1,
+ flags: self.0.table.get(&mail.1).ok_or(anyhow!("mail is missing from index"))?.1.as_ref(),
+ });
+ } else {
+ bail!("No such mail: {}", i);
+ }
+ }
+ }
+
+ Ok(mails)
+
+ }
+}
+
+pub struct MailIndex<'a> {
+ pub i: NonZeroU32,
+ pub uid: ImapUid,
+ pub uuid: UniqueIdent,
+ pub flags: &'a Vec<String>
+}
diff --git a/src/imap/mail_view.rs b/src/imap/mail_view.rs
index 94215dc..1f87f02 100644
--- a/src/imap/mail_view.rs
+++ b/src/imap/mail_view.rs
@@ -1,9 +1,9 @@
use std::num::NonZeroU32;
-use anyhow::{anyhow, bail, Result, Context};
+use anyhow::{anyhow, bail, Result};
use chrono::{Offset, TimeZone, Utc};
-use imap_codec::imap_types::core::{IString, NString};
+use imap_codec::imap_types::core::NString;
use imap_codec::imap_types::datetime::DateTime;
use imap_codec::imap_types::fetch::{
MessageDataItem, MessageDataItemName, Section as FetchSection,
@@ -16,87 +16,73 @@ use eml_codec::{
part::{composite::Message, AnyPart},
};
+
+use crate::mail::query::QueryResult;
+
use crate::imap::attributes::AttributesProxy;
use crate::imap::flags;
use crate::imap::imf_view::message_envelope;
-use crate::imap::mailbox_view::MailIdentifiers;
use crate::imap::mime_view;
use crate::imap::response::Body;
-use crate::mail::query::QueryResult;
+use crate::imap::index::MailIndex;
pub struct MailView<'a> {
+ pub in_idx: MailIndex<'a>,
pub query_result: &'a QueryResult<'a>,
pub content: FetchedMail<'a>,
}
impl<'a> MailView<'a> {
- pub fn new(query_result: &'a QueryResult<'a>) -> Result<Self> {
+ pub fn new(query_result: &'a QueryResult<'a>, in_idx: MailIndex<'a>) -> Result<MailView<'a>> {
Ok(Self {
+ in_idx,
query_result,
content: match query_result {
QueryResult::FullResult { content, .. } => {
- let (_, parsed) = eml_codec::parse_message(content).context("Invalid mail body")?;
+ let (_, parsed) = eml_codec::parse_message(&content).or(Err(anyhow!("Invalid mail body")))?;
FetchedMail::new_from_message(parsed)
},
QueryResult::PartialResult { metadata, .. } => {
- let (_, parsed) = eml_codec::parse_imf(&metadata.headers).context("Invalid mail headers")?;
+ let (_, parsed) = eml_codec::parse_imf(&metadata.headers).or(Err(anyhow!("unable to parse email headers")))?;
FetchedMail::Partial(parsed)
}
- QueryResult::IndexResult { .. } => FetchedMail::None,
+ QueryResult::IndexResult { .. } => FetchedMail::IndexOnly,
}
})
}
-
+
fn uid(&self) -> MessageDataItem<'static> {
- MessageDataItem::Uid(self.ids.uid.clone())
+ MessageDataItem::Uid(self.in_idx.uid.clone())
}
fn flags(&self) -> MessageDataItem<'static> {
MessageDataItem::Flags(
- self.flags
+ self.in_idx
+ .flags
.iter()
.filter_map(|f| flags::from_str(f))
.collect(),
)
}
- fn rfc_822_size(&self) -> MessageDataItem<'static> {
- MessageDataItem::Rfc822Size(self.meta.rfc822_size as u32)
+ fn rfc_822_size(&self) -> Result<MessageDataItem<'static>> {
+ let sz = self.query_result.metadata().ok_or(anyhow!("mail metadata are required"))?.rfc822_size;
+ Ok(MessageDataItem::Rfc822Size(sz as u32))
}
- fn rfc_822_header(&self) -> MessageDataItem<'static> {
- MessageDataItem::Rfc822Header(NString(
- self.meta
- .headers
- .to_vec()
- .try_into()
- .ok()
- .map(IString::Literal),
- ))
+ fn rfc_822_header(&self) -> Result<MessageDataItem<'static>> {
+ let hdrs: NString = self.query_result.metadata().ok_or(anyhow!("mail metadata are required"))?.headers.to_vec().try_into()?;
+ Ok(MessageDataItem::Rfc822Header(hdrs))
}
fn rfc_822_text(&self) -> Result<MessageDataItem<'static>> {
- Ok(MessageDataItem::Rfc822Text(NString(
- self.content
- .as_full()?
- .raw_body
- .to_vec()
- .try_into()
- .ok()
- .map(IString::Literal),
- )))
+ let txt: NString = self.content.as_full()?.raw_body.to_vec().try_into()?;
+ Ok(MessageDataItem::Rfc822Text(txt))
}
fn rfc822(&self) -> Result<MessageDataItem<'static>> {
- Ok(MessageDataItem::Rfc822(NString(
- self.content
- .as_full()?
- .raw_part
- .to_vec()
- .try_into()
- .ok()
- .map(IString::Literal),
- )))
+ let full: NString = self.content.as_full()?.raw_part.to_vec().try_into()?;
+ Ok(MessageDataItem::Rfc822(full))
}
fn envelope(&self) -> MessageDataItem<'static> {
@@ -119,16 +105,16 @@ impl<'a> MailView<'a> {
/// peek does not implicitly set the \Seen flag
/// eg. BODY[HEADER.FIELDS (DATE FROM)]
/// eg. BODY[]<0.2048>
- fn body_ext<'b>(
+ fn body_ext(
&self,
- section: &Option<FetchSection<'b>>,
+ section: &Option<FetchSection<'static>>,
partial: &Option<(u32, NonZeroU32)>,
peek: &bool,
- ) -> Result<(MessageDataItem<'b>, SeenFlag)> {
+ ) -> Result<(MessageDataItem<'static>, SeenFlag)> {
// Manage Seen flag
let mut seen = SeenFlag::DoNothing;
let seen_flag = Flag::Seen.to_string();
- if !peek && !self.flags.iter().any(|x| *x == seen_flag) {
+ if !peek && !self.in_idx.flags.iter().any(|x| *x == seen_flag) {
// Add \Seen flag
//self.mailbox.add_flags(uuid, &[seen_flag]).await?;
seen = SeenFlag::MustAdd;
@@ -141,7 +127,7 @@ impl<'a> MailView<'a> {
mime_view::BodySection::Slice { body, origin_octet } => (body, Some(origin_octet)),
};
- let data = NString(text.to_vec().try_into().ok().map(IString::Literal));
+ let data: NString = text.to_vec().try_into()?;
return Ok((
MessageDataItem::BodyExt {
@@ -156,13 +142,13 @@ impl<'a> MailView<'a> {
fn internal_date(&self) -> Result<MessageDataItem<'static>> {
let dt = Utc
.fix()
- .timestamp_opt(i64::try_from(self.meta.internaldate / 1000)?, 0)
+ .timestamp_opt(i64::try_from(self.query_result.metadata().ok_or(anyhow!("mail metadata were not fetched"))?.internaldate / 1000)?, 0)
.earliest()
.ok_or(anyhow!("Unable to parse internal date"))?;
Ok(MessageDataItem::InternalDate(DateTime::unvalidated(dt)))
}
- pub fn filter<'b>(&self, ap: &AttributesProxy) -> Result<(Body<'static>, SeenFlag)> {
+ pub fn filter(&self, ap: &AttributesProxy) -> Result<(Body<'static>, SeenFlag)> {
let mut seen = SeenFlag::DoNothing;
let res_attrs = ap
.attrs
@@ -170,8 +156,8 @@ impl<'a> MailView<'a> {
.map(|attr| match attr {
MessageDataItemName::Uid => Ok(self.uid()),
MessageDataItemName::Flags => Ok(self.flags()),
- MessageDataItemName::Rfc822Size => Ok(self.rfc_822_size()),
- MessageDataItemName::Rfc822Header => Ok(self.rfc_822_header()),
+ MessageDataItemName::Rfc822Size => self.rfc_822_size(),
+ MessageDataItemName::Rfc822Header => self.rfc_822_header(),
MessageDataItemName::Rfc822Text => self.rfc_822_text(),
MessageDataItemName::Rfc822 => self.rfc822(),
MessageDataItemName::Envelope => Ok(self.envelope()),
@@ -192,7 +178,7 @@ impl<'a> MailView<'a> {
Ok((
Body::Data(Data::Fetch {
- seq: self.ids.i,
+ seq: self.in_idx.i,
items: res_attrs.try_into()?,
}),
seen,
@@ -208,19 +194,15 @@ pub enum SeenFlag {
// -------------------
pub enum FetchedMail<'a> {
- None,
+ IndexOnly,
Partial(imf::Imf<'a>),
Full(AnyPart<'a>),
}
impl<'a> FetchedMail<'a> {
pub fn new_from_message(msg: Message<'a>) -> Self {
- FetchedMail::Full(AnyPart::Msg(msg))
+ Self::Full(AnyPart::Msg(msg))
}
- /*fn new_from_header(hdr: imf::Imf<'a>) -> Self {
- FetchedMail::Partial(hdr)
- }*/
-
fn as_anypart(&self) -> Result<&AnyPart<'a>> {
match self {
FetchedMail::Full(x) => Ok(&x),
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs
index 9cc72c1..5bc6f87 100644
--- a/src/imap/mailbox_view.rs
+++ b/src/imap/mailbox_view.rs
@@ -1,7 +1,7 @@
use std::num::NonZeroU32;
use std::sync::Arc;
-use anyhow::{anyhow, bail, Error, Result};
+use anyhow::{anyhow, Error, Result};
use futures::stream::{FuturesOrdered, StreamExt};
@@ -10,19 +10,19 @@ use imap_codec::imap_types::fetch::{MacroOrMessageDataItemNames, MessageDataItem
use imap_codec::imap_types::flag::{Flag, FlagFetch, FlagPerm, StoreResponse, StoreType};
use imap_codec::imap_types::response::{Code, Data, Status};
use imap_codec::imap_types::search::SearchKey;
-use imap_codec::imap_types::sequence::{self, SequenceSet};
+use imap_codec::imap_types::sequence::SequenceSet;
use crate::mail::mailbox::Mailbox;
use crate::mail::snapshot::FrozenMailbox;
use crate::mail::query::QueryScope;
use crate::mail::uidindex::{ImapUid, ImapUidvalidity};
-use crate::mail::unique_ident::UniqueIdent;
use crate::imap::attributes::AttributesProxy;
use crate::imap::flags;
use crate::imap::mail_view::{MailView, SeenFlag};
use crate::imap::response::Body;
-use crate::imap::search;
+//use crate::imap::search;
+use crate::imap::index::Index;
const DEFAULT_FLAGS: [Flag; 5] = [
@@ -147,7 +147,7 @@ impl MailboxView {
let flags = flags.iter().map(|x| x.to_string()).collect::<Vec<_>>();
- let mails = self.get_mail_ids(sequence_set, *is_uid_store)?;
+ let mails = self.index().fetch(sequence_set, *is_uid_store)?;
for mi in mails.iter() {
match kind {
StoreType::Add => {
@@ -190,7 +190,7 @@ impl MailboxView {
to: Arc<Mailbox>,
is_uid_copy: &bool,
) -> Result<(ImapUidvalidity, Vec<(ImapUid, ImapUid)>)> {
- let mails = self.get_mail_ids(sequence_set, *is_uid_copy)?;
+ let mails = self.index().fetch(sequence_set, *is_uid_copy)?;
let mut new_uuids = vec![];
for mi in mails.iter() {
@@ -217,7 +217,7 @@ impl MailboxView {
to: Arc<Mailbox>,
is_uid_copy: &bool,
) -> Result<(ImapUidvalidity, Vec<(ImapUid, ImapUid)>, Vec<Body<'static>>)> {
- let mails = self.get_mail_ids(sequence_set, *is_uid_copy)?;
+ let mails = self.index().fetch(sequence_set, *is_uid_copy)?;
for mi in mails.iter() {
to.move_from(&self.0.mailbox, mi.uuid).await?;
@@ -255,16 +255,17 @@ impl MailboxView {
true => QueryScope::Full,
_ => QueryScope::Partial,
};
- let mids = MailIdentifiersList(self.get_mail_ids(sequence_set, *is_uid_fetch)?);
- let uuids = mids.uuids();
+ let mail_idx_list = self.index().fetch(sequence_set, *is_uid_fetch)?;
// [2/6] Fetch the emails
+ let uuids = mail_idx_list.iter().map(|midx| midx.uuid).collect::<Vec<_>>();
let query = self.0.query(&uuids, query_scope);
let query_result = query.fetch().await?;
// [3/6] Derive an IMAP-specific view from the results, apply the filters
let views = query_result.iter()
- .map(MailView::new)
+ .zip(mail_idx_list.into_iter())
+ .map(|(qr, midx)| MailView::new(qr, midx))
.collect::<Result<Vec<_>, _>>()?;
// [4/6] Apply the IMAP transformation to keep only relevant fields
@@ -296,9 +297,10 @@ impl MailboxView {
pub async fn search<'a>(
&self,
_charset: &Option<Charset<'a>>,
- search_key: &SearchKey<'a>,
- uid: bool,
+ _search_key: &SearchKey<'a>,
+ _uid: bool,
) -> Result<Vec<Body<'static>>> {
+ /*
// 1. Compute the subset of sequence identifiers we need to fetch
let query = search::Criteria(search_key);
let (seq_set, seq_type) = query.to_sequence_set();
@@ -313,79 +315,15 @@ impl MailboxView {
let _need_body = query.need_body();
Ok(vec![Body::Data(Data::Search(mail_u32))])
+ */
+ unimplemented!()
}
// ----
-
- // Gets the IMAP ID, the IMAP UIDs and, the Aerogramme UUIDs of mails identified by a SequenceSet of
- // sequence numbers (~ IMAP selector)
- fn get_mail_ids(
- &self,
- sequence_set: &SequenceSet,
- by_uid: bool,
- ) -> Result<Vec<MailIdentifiers>> {
- let mail_vec = self
- .0
- .snapshot
- .idx_by_uid
- .iter()
- .map(|(uid, uuid)| (*uid, *uuid))
- .collect::<Vec<_>>();
-
- let mut mails = vec![];
-
- if by_uid {
- if mail_vec.is_empty() {
- return Ok(vec![]);
- }
- let iter_strat = sequence::Strategy::Naive {
- largest: mail_vec.last().unwrap().0,
- };
-
- let mut i = 0;
- for uid in sequence_set.iter(iter_strat) {
- while mail_vec.get(i).map(|mail| mail.0 < uid).unwrap_or(false) {
- i += 1;
- }
- if let Some(mail) = mail_vec.get(i) {
- if mail.0 == uid {
- mails.push(MailIdentifiers {
- i: NonZeroU32::try_from(i as u32 + 1).unwrap(),
- uid: mail.0,
- uuid: mail.1,
- });
- }
- } else {
- break;
- }
- }
- } else {
- if mail_vec.is_empty() {
- bail!("No such message (mailbox is empty)");
- }
-
- let iter_strat = sequence::Strategy::Naive {
- largest: NonZeroU32::try_from((mail_vec.len()) as u32).unwrap(),
- };
-
- for i in sequence_set.iter(iter_strat) {
- if let Some(mail) = mail_vec.get(i.get() as usize - 1) {
- mails.push(MailIdentifiers {
- i,
- uid: mail.0,
- uuid: mail.1,
- });
- } else {
- bail!("No such mail: {}", i);
- }
- }
- }
-
- Ok(mails)
+ fn index<'a>(&'a self) -> Index<'a> {
+ Index(&self.0.snapshot)
}
- // ----
-
/// Produce an OK [UIDVALIDITY _] message corresponding to `known_state`
fn uidvalidity_status(&self) -> Result<Body<'static>> {
let uid_validity = Status::ok(
@@ -501,25 +439,6 @@ impl MailboxView {
}
}
-pub struct MailIdentifiers {
- pub i: NonZeroU32,
- pub uid: ImapUid,
- pub uuid: UniqueIdent,
-}
-pub struct MailIdentifiersList(Vec<MailIdentifiers>);
-
-impl MailIdentifiersList {
- fn ids(&self) -> Vec<NonZeroU32> {
- self.0.iter().map(|mi| mi.i).collect()
- }
- fn uids(&self) -> Vec<ImapUid> {
- self.0.iter().map(|mi| mi.uid).collect()
- }
- fn uuids(&self) -> Vec<UniqueIdent> {
- self.0.iter().map(|mi| mi.uuid).collect()
- }
-}
-
#[cfg(test)]
mod tests {
use super::*;
@@ -558,7 +477,7 @@ mod tests {
message_key: key,
rfc822_size: 8usize,
};
- let ids = MailIdentifiers {
+ let ids = MailIndex {
i: NonZeroU32::MIN,
uid: NonZeroU32::MIN,
uuid: unique_ident::gen_ident(),
diff --git a/src/imap/mod.rs b/src/imap/mod.rs
index ea34629..4142ef9 100644
--- a/src/imap/mod.rs
+++ b/src/imap/mod.rs
@@ -4,12 +4,12 @@ mod command;
mod flags;
mod flow;
mod imf_view;
+mod index;
mod mail_view;
mod mailbox_view;
mod mime_view;
mod response;
mod search;
-mod selectors;
mod session;
use std::net::SocketAddr;
diff --git a/src/imap/selectors.rs b/src/imap/selectors.rs
deleted file mode 100644
index 09320c3..0000000
--- a/src/imap/selectors.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-use std::iter::zip;
-
-use anyhow::{anyhow, Result};
-
-use crate::cryptoblob::Key;
-use crate::imap::mail_view::{FetchedMail, MailView};
-use crate::imap::mailbox_view::MailIdentifiers;
-use crate::mail::mailbox::MailMeta;
-use crate::mail::unique_ident::UniqueIdent;
-
-pub struct BodyIdentifier<'a> {
- pub msg_uuid: &'a UniqueIdent,
- pub msg_key: &'a Key,
-}
-
-#[derive(Default)]
-pub struct MailSelectionBuilder<'a> {
- //attrs: AttributeProxy,
- mail_count: usize,
- need_body: bool,
- mi: &'a [MailIdentifiers],
- meta: &'a [MailMeta],
- flags: &'a [&'a Vec<String>],
- bodies: &'a [Vec<u8>],
-}
-
-impl<'a> MailSelectionBuilder<'a> {
- pub fn new(need_body: bool, mail_count: usize) -> Self {
- Self {
- mail_count,
- need_body,
- ..MailSelectionBuilder::default()
- }
- }
-
- pub fn with_mail_identifiers(&mut self, mi: &'a [MailIdentifiers]) -> &mut Self {
- self.mi = mi;
- self
- }
-
- pub fn with_metadata(&mut self, meta: &'a [MailMeta]) -> &mut Self {
- self.meta = meta;
- self
- }
-
- pub fn with_flags(&mut self, flags: &'a [&'a Vec<String>]) -> &mut Self {
- self.flags = flags;
- self
- }
-
- pub fn bodies_to_collect(&self) -> Vec<BodyIdentifier> {
- if !self.need_body {
- return vec![];
- }
- zip(self.mi, self.meta)
- .map(|(mi, meta)| BodyIdentifier {
- msg_uuid: &mi.uuid,
- msg_key: &meta.message_key,
- })
- .collect::<Vec<_>>()
- }
-
- pub fn with_bodies(&mut self, rbodies: &'a [Vec<u8>]) -> &mut Self {
- self.bodies = rbodies;
- self
- }
-
- pub fn build(&self) -> Result<Vec<MailView<'a>>> {
- let mut bodies = vec![];
-
- if !self.need_body {
- for m in self.meta.iter() {
- let (_, hdrs) =
- eml_codec::parse_imf(&m.headers).or(Err(anyhow!("Invalid mail headers")))?;
- bodies.push(FetchedMail::Partial(hdrs));
- }
- } else {
- for rb in self.bodies.iter() {
- let (_, p) = eml_codec::parse_message(&rb).or(Err(anyhow!("Invalid mail body")))?;
- bodies.push(FetchedMail::new_from_message(p));
- }
- }
-
- if self.mi.len() != self.mail_count && self.meta.len() != self.mail_count
- || self.flags.len() != self.mail_count
- || bodies.len() != self.mail_count
- {
- return Err(anyhow!("Can't build a mail view selection as parts were not correctly registered into the builder."));
- }
-
- Ok(zip(self.mi, zip(self.meta, zip(self.flags, bodies)))
- .map(|(ids, (meta, (flags, content)))| MailView {
- ids,
- meta,
- flags,
- content,
- })
- .collect())
- }
-}
diff --git a/src/mail/query.rs b/src/mail/query.rs
index 5beff37..70feb89 100644
--- a/src/mail/query.rs
+++ b/src/mail/query.rs
@@ -13,6 +13,7 @@ pub struct Query<'a,'b> {
pub scope: QueryScope,
}
+#[allow(dead_code)]
pub enum QueryScope {
Index,
Partial,
@@ -106,6 +107,7 @@ impl<'a> QueryResult<'a> {
}
}
+ #[allow(dead_code)]
pub fn index(&self) -> &IndexEntry {
match self {
Self::IndexResult { index, .. } => index,
@@ -114,7 +116,7 @@ impl<'a> QueryResult<'a> {
}
}
- pub fn metadata(&self) -> Option<&MailMeta> {
+ pub fn metadata(&'a self) -> Option<&'a MailMeta> {
match self {
Self::IndexResult { .. } => None,
Self::PartialResult { metadata, .. } => Some(metadata),
@@ -122,7 +124,8 @@ impl<'a> QueryResult<'a> {
}
}
- pub fn content(&self) -> Option<&[u8]> {
+ #[allow(dead_code)]
+ pub fn content(&'a self) -> Option<&'a [u8]> {
match self {
Self::FullResult { content, .. } => Some(content),
_ => None,