mirror of
https://github.com/soywod/himalaya.git
synced 2024-07-05 17:15:12 +00:00
add mailbox handler tests (#225)
* make imap.fetch_mboxes return a Mboxes struct * add mbox handler tests
This commit is contained in:
parent
8af14734c3
commit
85f3ce8976
|
@ -7,7 +7,7 @@ use anyhow::Result;
|
|||
use crate::{config::Config, domain::imap::ImapServiceInterface};
|
||||
|
||||
/// Notify handler.
|
||||
pub fn notify<ImapService: ImapServiceInterface>(
|
||||
pub fn notify<'a, ImapService: ImapServiceInterface<'a>>(
|
||||
keepalive: u64,
|
||||
config: &Config,
|
||||
imap: &mut ImapService,
|
||||
|
@ -16,7 +16,7 @@ pub fn notify<ImapService: ImapServiceInterface>(
|
|||
}
|
||||
|
||||
/// Watch handler.
|
||||
pub fn watch<ImapService: ImapServiceInterface>(
|
||||
pub fn watch<'a, ImapService: ImapServiceInterface<'a>>(
|
||||
keepalive: u64,
|
||||
imap: &mut ImapService,
|
||||
) -> Result<()> {
|
||||
|
|
|
@ -14,16 +14,15 @@ use std::{
|
|||
|
||||
use crate::{
|
||||
config::{Account, Config},
|
||||
domain::{Envelopes, Flags, Mbox, Msg},
|
||||
domain::{Envelopes, Flags, Mbox, Mboxes, Msg, RawMboxes},
|
||||
};
|
||||
|
||||
type ImapSession = imap::Session<TlsStream<TcpStream>>;
|
||||
pub(crate) type RawMboxes = imap::types::ZeroCopy<Vec<imap::types::Name>>;
|
||||
|
||||
pub trait ImapServiceInterface {
|
||||
pub trait ImapServiceInterface<'a> {
|
||||
fn notify(&mut self, config: &Config, keepalive: u64) -> Result<()>;
|
||||
fn watch(&mut self, keepalive: u64) -> Result<()>;
|
||||
fn fetch_raw_mboxes(&mut self) -> Result<RawMboxes>;
|
||||
fn fetch_mboxes(&'a mut self) -> Result<Mboxes>;
|
||||
fn get_msgs(&mut self, page_size: &usize, page: &usize) -> Result<Envelopes>;
|
||||
fn find_msgs(&mut self, query: &str, page_size: &usize, page: &usize) -> Result<Envelopes>;
|
||||
fn find_msg(&mut self, seq: &str) -> Result<Msg>;
|
||||
|
@ -45,6 +44,10 @@ pub struct ImapService<'a> {
|
|||
account: &'a Account,
|
||||
mbox: &'a Mbox<'a>,
|
||||
sess: Option<ImapSession>,
|
||||
/// Holds raw mailboxes fetched by the `imap` crate in order to extend mailboxes lifetime
|
||||
/// outside of handlers. Without that, it would be impossible for handlers to return a `Mbox`
|
||||
/// struct or a `Mboxes` struct due to the `ZeroCopy` constraint.
|
||||
_raw_mboxes_cache: Option<RawMboxes>,
|
||||
}
|
||||
|
||||
impl<'a> ImapService<'a> {
|
||||
|
@ -102,11 +105,14 @@ impl<'a> ImapService<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> ImapServiceInterface for ImapService<'a> {
|
||||
fn fetch_raw_mboxes(&mut self) -> Result<RawMboxes> {
|
||||
self.sess()?
|
||||
impl<'a> ImapServiceInterface<'a> for ImapService<'a> {
|
||||
fn fetch_mboxes(&'a mut self) -> Result<Mboxes> {
|
||||
let raw_mboxes = self
|
||||
.sess()?
|
||||
.list(Some(""), Some("*"))
|
||||
.context("cannot list mailboxes")
|
||||
.context("cannot list mailboxes")?;
|
||||
self._raw_mboxes_cache = Some(raw_mboxes);
|
||||
Ok(Mboxes::from(self._raw_mboxes_cache.as_ref().unwrap()))
|
||||
}
|
||||
|
||||
fn get_msgs(&mut self, page_size: &usize, page: &usize) -> Result<Envelopes> {
|
||||
|
@ -381,6 +387,7 @@ impl<'a> From<(&'a Account, &'a Mbox<'a>)> for ImapService<'a> {
|
|||
account,
|
||||
mbox,
|
||||
sess: None,
|
||||
_raw_mboxes_cache: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub enum AttrWrap<'a> {
|
|||
/// Represents the mailbox attribute.
|
||||
/// See https://serde.rs/remote-derive.html.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct Attr<'a>(#[serde(with = "AttrWrap")] pub &'a AttrRemote<'a>);
|
||||
pub struct Attr<'a>(#[serde(with = "AttrWrap")] pub AttrRemote<'a>);
|
||||
|
||||
/// Makes the attribute displayable.
|
||||
impl<'a> Display for Attr<'a> {
|
||||
|
@ -39,6 +39,13 @@ impl<'a> Display for Attr<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts an `imap::types::NameAttribute` into an attribute.
|
||||
impl<'a> From<AttrRemote<'a>> for Attr<'a> {
|
||||
fn from(attr: AttrRemote<'a>) -> Self {
|
||||
Self(attr)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -47,10 +54,10 @@ mod tests {
|
|||
fn it_should_display_attr() {
|
||||
macro_rules! attr_from {
|
||||
($attr:ident) => {
|
||||
Attr(&AttrRemote::$attr).to_string()
|
||||
Attr(AttrRemote::$attr).to_string()
|
||||
};
|
||||
($custom:literal) => {
|
||||
Attr(&AttrRemote::Custom($custom.into())).to_string()
|
||||
Attr(AttrRemote::Custom($custom.into())).to_string()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
use serde::Serialize;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fmt::{self, Display},
|
||||
ops::Deref,
|
||||
};
|
||||
|
@ -12,20 +11,19 @@ use std::{
|
|||
use crate::domain::{Attr, AttrRemote};
|
||||
|
||||
/// Represents the attributes of the mailbox.
|
||||
/// A HashSet is used in order to avoid duplicates.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Serialize)]
|
||||
pub struct Attrs<'a>(HashSet<Attr<'a>>);
|
||||
pub struct Attrs<'a>(Vec<Attr<'a>>);
|
||||
|
||||
/// Converts a slice of `imap::types::NameAttribute` into attributes.
|
||||
impl<'a> From<&'a [AttrRemote<'a>]> for Attrs<'a> {
|
||||
fn from(attrs: &'a [AttrRemote<'a>]) -> Self {
|
||||
Self(attrs.iter().map(Attr).collect())
|
||||
/// Converts a vector of `imap::types::NameAttribute` into attributes.
|
||||
impl<'a> From<Vec<AttrRemote<'a>>> for Attrs<'a> {
|
||||
fn from(attrs: Vec<AttrRemote<'a>>) -> Self {
|
||||
Self(attrs.into_iter().map(Attr::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// Derefs the attributes to its inner hashset.
|
||||
impl<'a> Deref for Attrs<'a> {
|
||||
type Target = HashSet<Attr<'a>>;
|
||||
type Target = Vec<Attr<'a>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
|
@ -52,7 +50,7 @@ mod tests {
|
|||
fn it_should_display_attrs() {
|
||||
macro_rules! attrs_from {
|
||||
($($attr:expr),*) => {
|
||||
Attrs::from(&[$($attr,)*] as &[AttrRemote]).to_string()
|
||||
Attrs::from(vec![$($attr,)*]).to_string()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ use crate::{
|
|||
ui::{Cell, Row, Table},
|
||||
};
|
||||
|
||||
/// Represents the mailbox.
|
||||
/// Represents a raw mailbox returned by the `imap` crate.
|
||||
pub(crate) type RawMbox = imap::types::Name;
|
||||
|
||||
/// Represents a mailbox.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Serialize)]
|
||||
pub struct Mbox<'a> {
|
||||
/// Represents the mailbox hierarchie delimiter.
|
||||
|
@ -68,11 +71,11 @@ impl<'a> Table for Mbox<'a> {
|
|||
|
||||
/// Converts an `imap::types::Name` into a mailbox.
|
||||
impl<'a> From<&'a imap::types::Name> for Mbox<'a> {
|
||||
fn from(name: &'a imap::types::Name) -> Self {
|
||||
fn from(raw_mbox: &'a imap::types::Name) -> Self {
|
||||
Self {
|
||||
delim: name.delimiter().unwrap_or_default().into(),
|
||||
name: name.name().into(),
|
||||
attrs: Attrs::from(name.attributes()),
|
||||
delim: raw_mbox.delimiter().unwrap_or_default().into(),
|
||||
name: raw_mbox.name().into(),
|
||||
attrs: Attrs::from(raw_mbox.attributes().to_vec()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +109,7 @@ mod tests {
|
|||
let full_mbox = Mbox {
|
||||
delim: ".".into(),
|
||||
name: "Sent".into(),
|
||||
attrs: Attrs::from(&[AttrRemote::NoSelect] as &[AttrRemote]),
|
||||
attrs: Attrs::from(vec![AttrRemote::NoSelect]),
|
||||
};
|
||||
assert_eq!("Sent", full_mbox.to_string());
|
||||
}
|
||||
|
|
|
@ -5,18 +5,126 @@
|
|||
use anyhow::Result;
|
||||
use log::trace;
|
||||
|
||||
use crate::{
|
||||
domain::{ImapServiceInterface, Mboxes},
|
||||
output::OutputServiceInterface,
|
||||
};
|
||||
use crate::{domain::ImapServiceInterface, output::OutputServiceInterface};
|
||||
|
||||
/// List all mailboxes.
|
||||
pub fn list<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn list<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
output: &OutputService,
|
||||
imap: &mut ImapService,
|
||||
imap: &'a mut ImapService,
|
||||
) -> Result<()> {
|
||||
let raw_mboxes = imap.fetch_raw_mboxes()?;
|
||||
let mboxes = Mboxes::from(&raw_mboxes);
|
||||
let mboxes = imap.fetch_mboxes()?;
|
||||
trace!("mailboxes: {:#?}", mboxes);
|
||||
output.print(mboxes)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde::Serialize;
|
||||
use std::fmt::Display;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
config::Config,
|
||||
domain::{AttrRemote, Attrs, Envelopes, Flags, Mbox, Mboxes, Msg},
|
||||
output::OutputJson,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn it_should_list_mboxes() {
|
||||
struct OutputServiceTest;
|
||||
|
||||
impl OutputServiceInterface for OutputServiceTest {
|
||||
fn print<T: Serialize + Display>(&self, data: T) -> Result<()> {
|
||||
let data = serde_json::to_string(&OutputJson::new(data))?;
|
||||
assert_eq!(
|
||||
data,
|
||||
r#"{"response":[{"delim":"/","name":"INBOX","attrs":["NoSelect"]},{"delim":"/","name":"Sent","attrs":["NoInferiors",{"Custom":"HasNoChildren"}]}]}"#
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_json(&self) -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
struct ImapServiceTest;
|
||||
|
||||
impl<'a> ImapServiceInterface<'a> for ImapServiceTest {
|
||||
fn fetch_mboxes(&'a mut self) -> Result<Mboxes> {
|
||||
Ok(Mboxes(vec![
|
||||
Mbox {
|
||||
delim: "/".into(),
|
||||
name: "INBOX".into(),
|
||||
attrs: Attrs::from(vec![AttrRemote::NoSelect]),
|
||||
},
|
||||
Mbox {
|
||||
delim: "/".into(),
|
||||
name: "Sent".into(),
|
||||
attrs: Attrs::from(vec![
|
||||
AttrRemote::NoInferiors,
|
||||
AttrRemote::Custom("HasNoChildren".into()),
|
||||
]),
|
||||
},
|
||||
]))
|
||||
}
|
||||
|
||||
fn notify(&mut self, _: &Config, _: u64) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn watch(&mut self, _: u64) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_msgs(&mut self, _: &usize, _: &usize) -> Result<Envelopes> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn find_msgs(&mut self, _: &str, _: &usize, _: &usize) -> Result<Envelopes> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn find_msg(&mut self, _: &str) -> Result<Msg> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn find_raw_msg(&mut self, _: &str) -> Result<Vec<u8>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn append_msg(&mut self, _: &Mbox, _: Msg) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn append_raw_msg_with_flags(&mut self, _: &Mbox, _: &[u8], _: Flags) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn expunge(&mut self) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn logout(&mut self) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn add_flags(&mut self, _: &str, _: &Flags) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn set_flags(&mut self, _: &str, _: &Flags) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn remove_flags(&mut self, _: &str, _: &Flags) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
let output = OutputServiceTest {};
|
||||
let mut imap = ImapServiceTest {};
|
||||
|
||||
assert!(list(&output, &mut imap).is_ok());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,16 @@ use std::{
|
|||
ops::Deref,
|
||||
};
|
||||
|
||||
use crate::{domain::Mbox, ui::Table};
|
||||
use crate::{
|
||||
domain::{Mbox, RawMbox},
|
||||
ui::Table,
|
||||
};
|
||||
|
||||
/// Represents a list of raw mailboxes returned by the `imap` crate.
|
||||
pub(crate) type RawMboxes = imap::types::ZeroCopy<Vec<RawMbox>>;
|
||||
|
||||
/// Represents a list of mailboxes.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
pub struct Mboxes<'a>(pub Vec<Mbox<'a>>);
|
||||
|
||||
/// Derefs the mailboxes to its inner vector.
|
||||
|
@ -31,8 +37,8 @@ impl<'a> Display for Mboxes<'a> {
|
|||
}
|
||||
|
||||
/// Converts a list of `imap::types::Name` into mailboxes.
|
||||
impl<'a> From<&'a imap::types::ZeroCopy<Vec<imap::types::Name>>> for Mboxes<'a> {
|
||||
fn from(names: &'a imap::types::ZeroCopy<Vec<imap::types::Name>>) -> Self {
|
||||
Self(names.iter().map(Mbox::from).collect())
|
||||
impl<'a> From<&'a RawMboxes> for Mboxes<'a> {
|
||||
fn from(raw_mboxes: &'a RawMboxes) -> Mboxes<'a> {
|
||||
Self(raw_mboxes.iter().map(Mbox::from).collect())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
|
||||
/// Add flags to all messages within the given sequence range.
|
||||
/// Flags are case-insensitive, and they do not need to be prefixed with `\`.
|
||||
pub fn add<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn add<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq_range: &'a str,
|
||||
flags: Vec<&'a str>,
|
||||
output: &'a OutputService,
|
||||
|
@ -27,7 +27,7 @@ pub fn add<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceIn
|
|||
|
||||
/// Remove flags from all messages within the given sequence range.
|
||||
/// Flags are case-insensitive, and they do not need to be prefixed with `\`.
|
||||
pub fn remove<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn remove<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq_range: &'a str,
|
||||
flags: Vec<&'a str>,
|
||||
output: &'a OutputService,
|
||||
|
@ -43,7 +43,7 @@ pub fn remove<'a, OutputService: OutputServiceInterface, ImapService: ImapServic
|
|||
|
||||
/// Replace flags of all messages within the given sequence range.
|
||||
/// Flags are case-insensitive, and they do not need to be prefixed with `\`.
|
||||
pub fn set<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn set<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq_range: &'a str,
|
||||
flags: Vec<&'a str>,
|
||||
output: &'a OutputService,
|
||||
|
|
|
@ -296,8 +296,9 @@ impl Msg {
|
|||
}
|
||||
|
||||
pub fn edit_with_editor<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
mut self,
|
||||
|
|
|
@ -26,7 +26,11 @@ use crate::{
|
|||
};
|
||||
|
||||
/// Download all message attachments to the user account downloads directory.
|
||||
pub fn attachments<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn attachments<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
>(
|
||||
seq: &str,
|
||||
account: &Account,
|
||||
output: &OutputService,
|
||||
|
@ -53,7 +57,7 @@ pub fn attachments<OutputService: OutputServiceInterface, ImapService: ImapServi
|
|||
}
|
||||
|
||||
/// Copy a message from a mailbox to another.
|
||||
pub fn copy<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn copy<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq: &str,
|
||||
mbox: &str,
|
||||
output: &OutputService,
|
||||
|
@ -70,7 +74,7 @@ pub fn copy<OutputService: OutputServiceInterface, ImapService: ImapServiceInter
|
|||
}
|
||||
|
||||
/// Delete messages matching the given sequence range.
|
||||
pub fn delete<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn delete<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq: &str,
|
||||
output: &OutputService,
|
||||
imap: &mut ImapService,
|
||||
|
@ -83,8 +87,9 @@ pub fn delete<OutputService: OutputServiceInterface, ImapService: ImapServiceInt
|
|||
|
||||
/// Forward the given message UID from the selected mailbox.
|
||||
pub fn forward<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
seq: &str,
|
||||
|
@ -101,7 +106,7 @@ pub fn forward<
|
|||
}
|
||||
|
||||
/// List paginated messages from the selected mailbox.
|
||||
pub fn list<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn list<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
page_size: Option<usize>,
|
||||
page: usize,
|
||||
account: &Account,
|
||||
|
@ -120,8 +125,9 @@ pub fn list<OutputService: OutputServiceInterface, ImapService: ImapServiceInter
|
|||
///
|
||||
/// [mailto]: https://en.wikipedia.org/wiki/Mailto
|
||||
pub fn mailto<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
url: &Url,
|
||||
|
@ -172,7 +178,7 @@ pub fn mailto<
|
|||
}
|
||||
|
||||
/// Move a message from a mailbox to another.
|
||||
pub fn move_<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn move_<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
// The sequence number of the message to move
|
||||
seq: &str,
|
||||
// The mailbox to move the message in
|
||||
|
@ -198,7 +204,7 @@ pub fn move_<OutputService: OutputServiceInterface, ImapService: ImapServiceInte
|
|||
}
|
||||
|
||||
/// Read a message by its sequence number.
|
||||
pub fn read<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn read<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq: &str,
|
||||
text_mime: &str,
|
||||
raw: bool,
|
||||
|
@ -216,8 +222,9 @@ pub fn read<OutputService: OutputServiceInterface, ImapService: ImapServiceInter
|
|||
|
||||
/// Reply to the given message UID.
|
||||
pub fn reply<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
seq: &str,
|
||||
|
@ -237,7 +244,7 @@ pub fn reply<
|
|||
}
|
||||
|
||||
/// Save a raw message to the targetted mailbox.
|
||||
pub fn save<ImapService: ImapServiceInterface>(
|
||||
pub fn save<'a, ImapService: ImapServiceInterface<'a>>(
|
||||
mbox: &str,
|
||||
msg: &str,
|
||||
imap: &mut ImapService,
|
||||
|
@ -248,7 +255,7 @@ pub fn save<ImapService: ImapServiceInterface>(
|
|||
}
|
||||
|
||||
/// Paginate messages from the selected mailbox matching the specified query.
|
||||
pub fn search<OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn search<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
query: String,
|
||||
page_size: Option<usize>,
|
||||
page: usize,
|
||||
|
@ -266,8 +273,9 @@ pub fn search<OutputService: OutputServiceInterface, ImapService: ImapServiceInt
|
|||
|
||||
/// Send a raw message.
|
||||
pub fn send<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
raw_msg: &str,
|
||||
|
@ -301,8 +309,9 @@ pub fn send<
|
|||
|
||||
/// Compose a new message.
|
||||
pub fn write<
|
||||
'a,
|
||||
OutputService: OutputServiceInterface,
|
||||
ImapService: ImapServiceInterface,
|
||||
ImapService: ImapServiceInterface<'a>,
|
||||
SmtpService: SmtpServiceInterface,
|
||||
>(
|
||||
attachments_paths: Vec<&str>,
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn new<'a, OutputService: OutputServiceInterface>(
|
|||
}
|
||||
|
||||
/// Generate a reply message template.
|
||||
pub fn reply<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn reply<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq: &str,
|
||||
all: bool,
|
||||
opts: TplOverride<'a>,
|
||||
|
@ -39,7 +39,7 @@ pub fn reply<'a, OutputService: OutputServiceInterface, ImapService: ImapService
|
|||
}
|
||||
|
||||
/// Generate a forward message template.
|
||||
pub fn forward<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface>(
|
||||
pub fn forward<'a, OutputService: OutputServiceInterface, ImapService: ImapServiceInterface<'a>>(
|
||||
seq: &str,
|
||||
opts: TplOverride<'a>,
|
||||
account: &'a Account,
|
||||
|
|
Loading…
Reference in a new issue