deltachat::imap::session

Struct Session

source
pub(crate) struct Session {
    pub(super) inner: Session<Box<dyn SessionStream>>,
    pub capabilities: Capabilities,
    pub selected_folder: Option<String>,
    pub selected_mailbox: Option<Mailbox>,
    pub selected_folder_needs_expunge: bool,
    pub new_mail: bool,
}

Fields§

§inner: Session<Box<dyn SessionStream>>§capabilities: Capabilities§selected_folder: Option<String>

Selected folder name.

§selected_mailbox: Option<Mailbox>

Mailbox structure returned by IMAP server.

§selected_folder_needs_expunge: bool§new_mail: bool

True if currently selected folder has new messages.

Should be false if no folder is currently selected.

Implementations§

source§

impl Session

source

async fn fetch_single_msg( &mut self, context: &Context, folder: &str, uidvalidity: u32, uid: u32, rfc724_mid: String, ) -> Result<()>

Download a single message and pipe it to receive_imf().

receive_imf() is not directly aware that this is a result of a call to download_msg(), however, implicitly knows that as the existing message is flagged as being partly.

source§

impl Session

source

pub async fn idle( self, context: &Context, idle_interrupt_receiver: Receiver<()>, folder: &str, ) -> Result<Self>

source§

impl Session

source

pub(super) async fn maybe_close_folder( &mut self, context: &Context, ) -> Result<()>

Issues a CLOSE command if selected folder needs expunge, i.e. if Delta Chat marked a message there as deleted previously.

CLOSE is considerably faster than an EXPUNGE because no EXPUNGE responses are sent, see https://tools.ietf.org/html/rfc3501#section-6.4.2

source

async fn select_folder( &mut self, context: &Context, folder: &str, ) -> Result<NewlySelected, Error>

Selects a folder, possibly updating uid_validity and, if needed, expunging the folder to remove delete-marked messages. Returns whether a new folder was selected.

source

pub(super) async fn select_or_create_folder( &mut self, context: &Context, folder: &str, ) -> Result<NewlySelected>

Selects a folder. Tries to create it once and select again if the folder does not exist.

source

pub(crate) async fn select_with_uidvalidity( &mut self, context: &Context, folder: &str, ) -> Result<(), Error>

Selects a folder and takes care of UIDVALIDITY changes.

When selecting a folder for the first time, sets the uid_next to the current mailbox.uid_next so that no old emails are fetched.

Updates self.new_mail if folder was previously unselected and new mails are detected after selecting, i.e. UIDNEXT advanced while the folder was closed.

source§

impl Session

source

pub(crate) fn new( inner: ImapSession<Box<dyn SessionStream>>, capabilities: Capabilities, ) -> Self

source

pub fn can_idle(&self) -> bool

source

pub fn can_move(&self) -> bool

source

pub fn can_check_quota(&self) -> bool

source

pub fn can_condstore(&self) -> bool

source

pub fn can_metadata(&self) -> bool

source

pub fn can_push(&self) -> bool

source

pub fn is_chatmail(&self) -> bool

source

pub async fn list_folders(&mut self) -> Result<Vec<Name>>

Returns the names of all folders on the IMAP server.

source

pub(crate) async fn prefetch( &mut self, uid_next: u32, ) -> Result<Vec<(u32, Fetch)>>

Prefetch all messages greater than or equal to uid_next. Returns a list of fetch results in the order of ascending delivery time to the server (INTERNALDATE).

source

pub(crate) async fn prefetch_existing_msgs( &mut self, ) -> Result<Vec<(u32, Fetch)>>

Like prefetch(), but not for new messages but existing ones (the DC_FETCH_EXISTING_MSGS_COUNT newest messages)

source§

impl Session

source

pub(crate) async fn resync_folders(&mut self, context: &Context) -> Result<()>

Synchronizes UIDs for all folders.

source

pub(crate) async fn resync_folder_uids( &mut self, context: &Context, folder: &str, folder_meaning: FolderMeaning, ) -> Result<()>

Synchronizes UIDs in the database with UIDs on the server.

It is assumed that no operations are taking place on the same folder at the moment. Make sure to run it in the same thread/task as other network operations on this folder to avoid race conditions.

source

async fn delete_message_batch( &mut self, context: &Context, uid_set: &str, row_ids: Vec<i64>, ) -> Result<()>

Deletes batch of messages identified by their UID from the currently selected folder.

source

async fn move_message_batch( &mut self, context: &Context, set: &str, row_ids: Vec<i64>, target: &str, ) -> Result<()>

Moves batch of messages identified by their UID from the currently selected folder to the target folder.

source

async fn move_delete_messages( &mut self, context: &Context, folder: &str, ) -> Result<()>

Moves and deletes messages as planned in the imap table.

This is the only place where messages are moved or deleted on the IMAP server.

source

pub(crate) async fn send_sync_msgs( &mut self, context: &Context, folder: &str, ) -> Result<()>

Uploads sync messages from the imap_send table with \Seen flag set.

source

pub(crate) async fn store_seen_flags_on_imap( &mut self, context: &Context, ) -> Result<()>

Stores pending \Seen flags for messages in imap_markseen table.

source

pub(crate) async fn sync_seen_flags( &mut self, context: &Context, folder: &str, ) -> Result<()>

Synchronizes \Seen flags using CONDSTORE extension.

source

pub async fn get_all_recipients( &mut self, context: &Context, ) -> Result<Vec<SingleInfo>>

Gets the from, to and bcc addresses from all existing outgoing emails.

source

pub(crate) async fn fetch_many_msgs( &mut self, context: &Context, folder: &str, uidvalidity: u32, request_uids: Vec<u32>, uid_message_ids: &BTreeMap<u32, String>, fetch_partially: bool, fetching_existing_messages: bool, ) -> Result<(Option<u32>, Vec<ReceivedMsg>)>

Fetches a list of messages by server UID.

Returns the last UID fetched successfully and the info about each downloaded message. If the message is incorrect or there is a failure to write a message to the database, it is skipped and the error is logged.

source

pub(crate) async fn fetch_metadata(&mut self, context: &Context) -> Result<()>

Retrieves server metadata if it is supported.

We get /shared/comment and /shared/admin metadata.

source

pub(crate) async fn register_token(&mut self, context: &Context) -> Result<()>

Stores device token into /private/devicetoken IMAP METADATA of the Inbox.

source§

impl Session

source

async fn add_flag_finalized_with_set( &mut self, uid_set: &str, flag: &str, ) -> Result<()>

Returns success if we successfully set the flag or we otherwise think add_flag should not be retried: Disconnection during setting the flag, or other imap-errors, returns true as well.

Returning error means that the operation can be retried.

source

async fn configure_mvbox<'a>( &mut self, context: &Context, folders: &[&'a str], create_mvbox: bool, ) -> Result<Option<&'a str>>

Attempts to configure mvbox.

Tries to find any folder examining folders in the order they go. If none is found, tries to create any folder in the same order. This method does not use LIST command to ensure that configuration works even if mailbox lookup is forbidden via Access Control List (see https://datatracker.ietf.org/doc/html/rfc4314).

Returns first found or created folder name.

source§

impl Session

source

fn drain_unsolicited_responses(&self, context: &Context) -> Result<bool>

Return whether the server sent an unsolicited EXISTS or FETCH response.

Drains all responses from session.unsolicited_responses in the process.

If this returns true, this means that new emails arrived or flags have been changed. In this case we may want to skip next IDLE and do a round of fetching new messages and synchronizing seen flags.

Methods from Deref<Target = ImapSession<Box<dyn SessionStream>>>§

pub async fn select<S>(&mut self, mailbox_name: S) -> Result<Mailbox, Error>
where S: AsRef<str>,

Selects a mailbox.

The SELECT command selects a mailbox so that messages in the mailbox can be accessed. Note that earlier versions of this protocol only required the FLAGS, EXISTS, and RECENT untagged data; consequently, client implementations SHOULD implement default behavior for missing data as discussed with the individual item.

Only one mailbox can be selected at a time in a connection; simultaneous access to multiple mailboxes requires multiple connections. The SELECT command automatically deselects any currently selected mailbox before attempting the new selection. Consequently, if a mailbox is selected and a SELECT command that fails is attempted, no mailbox is selected.

Note that the server is allowed to unilaterally send things to the client for messages in a selected mailbox whose status has changed. See the note on unilateral server responses in RFC 3501. This means that if run commands, you may see additional untagged RECENT, EXISTS, FETCH, and EXPUNGE responses. You can get them from the unsolicited_responses channel of the Session.

pub async fn select_condstore<S>( &mut self, mailbox_name: S, ) -> Result<Mailbox, Error>
where S: AsRef<str>,

Selects a mailbox with (CONDSTORE) parameter as defined in RFC 7162.

pub async fn examine<S>(&mut self, mailbox_name: S) -> Result<Mailbox, Error>
where S: AsRef<str>,

The EXAMINE command is identical to [Session::select] and returns the same output; however, the selected mailbox is identified as read-only. No changes to the permanent state of the mailbox, including per-user state, will happen in a mailbox opened with examine; in particular, messagess cannot lose [Flag::Recent] in an examined mailbox.

pub async fn fetch<S1, S2>( &mut self, sequence_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
where S1: AsRef<str>, S2: AsRef<str>,

Fetch retreives data associated with a set of messages in the mailbox.

Note that the server is allowed to unilaterally include FETCH responses for other messages in the selected mailbox whose status has changed. See the note on unilateral server responses in RFC 3501.

query is a list of “data items” (space-separated in parentheses if >1). There are three “macro items” which specify commonly-used sets of data items, and can be used instead of data items. A macro must be used by itself, and not in conjunction with other macros or data items. They are:

  • ALL: equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)
  • FAST: equivalent to: (FLAGS INTERNALDATE RFC822.SIZE)

The currently defined data items that can be fetched are listen in the RFC, but here are some common ones:

  • FLAGS: The flags that are set for this message.

  • INTERNALDATE: The internal date of the message.

  • BODY[<section>]:

    The text of a particular body section. The section specification is a set of zero or more part specifiers delimited by periods. A part specifier is either a part number (see RFC) or one of the following: HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT. An empty section specification (i.e., BODY[]) refers to the entire message, including the header.

    The HEADER, HEADER.FIELDS, and HEADER.FIELDS.NOT part specifiers refer to the RFC-2822 header of the message or of an encapsulated MIME-IMT MESSAGE/RFC822 message. HEADER.FIELDS and HEADER.FIELDS.NOT are followed by a list of field-name (as defined in RFC-2822) names, and return a subset of the header. The subset returned by HEADER.FIELDS contains only those header fields with a field-name that matches one of the names in the list; similarly, the subset returned by HEADER.FIELDS.NOT contains only the header fields with a non-matching field-name. The field-matching is case-insensitive but otherwise exact. Subsetting does not exclude the RFC-2822 delimiting blank line between the header and the body; the blank line is included in all header fetches, except in the case of a message which has no body and no blank line.

    The MIME part specifier refers to the MIME-IMB header for this part.

    The TEXT part specifier refers to the text body of the message, omitting the RFC-2822 header.

    [Flag::Seen] is implicitly set when BODY is fetched; if this causes the flags to change, they will generally be included as part of the FETCH responses.

  • BODY.PEEK[<section>]: An alternate form of BODY[<section>] that does not implicitly set [Flag::Seen].

  • ENVELOPE: The envelope structure of the message. This is computed by the server by parsing the RFC-2822 header into the component parts, defaulting various fields as necessary.

  • RFC822: Functionally equivalent to BODY[].

  • RFC822.HEADER: Functionally equivalent to BODY.PEEK[HEADER].

  • RFC822.SIZE: The RFC-2822 size of the message.

  • UID: The unique identifier for the message.

pub async fn uid_fetch<S1, S2>( &mut self, uid_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send + Unpin, Error>
where S1: AsRef<str>, S2: AsRef<str>,

Equivalent to [Session::fetch], except that all identifiers in uid_set are [Uid]s. See also the UID command.

pub async fn noop(&mut self) -> Result<(), Error>

Noop always succeeds, and it does nothing.

pub async fn logout(&mut self) -> Result<(), Error>

Logout informs the server that the client is done with the connection.

pub async fn create<S>(&mut self, mailbox_name: S) -> Result<(), Error>
where S: AsRef<str>,

The CREATE command creates a mailbox with the given name. Ok is returned only if a new mailbox with that name has been created. It is an error to attempt to create INBOX or a mailbox with a name that refers to an extant mailbox. Any error in creation will return [Error::No].

If the mailbox name is suffixed with the server’s hierarchy separator character (as returned from the server by [Session::list]), this is a declaration that the client intends to create mailbox names under this name in the hierarchy. Servers that do not require this declaration will ignore the declaration. In any case, the name created is without the trailing hierarchy delimiter.

If the server’s hierarchy separator character appears elsewhere in the name, the server will generally create any superior hierarchical names that are needed for the CREATE command to be successfully completed. In other words, an attempt to create foo/bar/zap on a server in which / is the hierarchy separator character will usually create foo/ and foo/bar/ if they do not already exist.

If a new mailbox is created with the same name as a mailbox which was deleted, its unique identifiers will be greater than any unique identifiers used in the previous incarnation of the mailbox UNLESS the new incarnation has a different unique identifier validity value. See the description of the UID command for more detail.

pub async fn delete<S>(&mut self, mailbox_name: S) -> Result<(), Error>
where S: AsRef<str>,

The DELETE command permanently removes the mailbox with the given name. Ok is returned only if the mailbox has been deleted. It is an error to attempt to delete INBOX or a mailbox name that does not exist.

The DELETE command will not remove inferior hierarchical names. For example, if a mailbox foo has an inferior foo.bar (assuming . is the hierarchy delimiter character), removing foo will not remove foo.bar. It is an error to attempt to delete a name that has inferior hierarchical names and also has [NameAttribute::NoSelect].

It is permitted to delete a name that has inferior hierarchical names and does not have [NameAttribute::NoSelect]. In this case, all messages in that mailbox are removed, and the name will acquire [NameAttribute::NoSelect].

The value of the highest-used unique identifier of the deleted mailbox will be preserved so that a new mailbox created with the same name will not reuse the identifiers of the former incarnation, UNLESS the new incarnation has a different unique identifier validity value. See the description of the UID command for more detail.

pub async fn rename<S1, S2>(&mut self, from: S1, to: S2) -> Result<(), Error>
where S1: AsRef<str>, S2: AsRef<str>,

The RENAME command changes the name of a mailbox. Ok is returned only if the mailbox has been renamed. It is an error to attempt to rename from a mailbox name that does not exist or to a mailbox name that already exists. Any error in renaming will return [Error::No].

If the name has inferior hierarchical names, then the inferior hierarchical names will also be renamed. For example, a rename of foo to zap will rename foo/bar (assuming / is the hierarchy delimiter character) to zap/bar.

If the server’s hierarchy separator character appears in the name, the server will generally create any superior hierarchical names that are needed for the RENAME command to complete successfully. In other words, an attempt to rename foo/bar/zap to baz/rag/zowie on a server in which / is the hierarchy separator character will generally create baz/ and baz/rag/ if they do not already exist.

The value of the highest-used unique identifier of the old mailbox name will be preserved so that a new mailbox created with the same name will not reuse the identifiers of the former incarnation, UNLESS the new incarnation has a different unique identifier validity value. See the description of the UID command for more detail.

Renaming INBOX is permitted, and has special behavior. It moves all messages in INBOX to a new mailbox with the given name, leaving INBOX empty. If the server implementation supports inferior hierarchical names of INBOX, these are unaffected by a rename of INBOX.

pub async fn subscribe<S>(&mut self, mailbox: S) -> Result<(), Error>
where S: AsRef<str>,

The SUBSCRIBE command adds the specified mailbox name to the server’s set of “active” or “subscribed” mailboxes as returned by [Session::lsub]. This command returns Ok only if the subscription is successful.

The server may validate the mailbox argument to SUBSCRIBE to verify that it exists. However, it will not unilaterally remove an existing mailbox name from the subscription list even if a mailbox by that name no longer exists.

pub async fn unsubscribe<S>(&mut self, mailbox: S) -> Result<(), Error>
where S: AsRef<str>,

The UNSUBSCRIBE command removes the specified mailbox name from the server’s set of “active” or “subscribed” mailboxes as returned by [Session::lsub]. This command returns Ok only if the unsubscription is successful.

pub async fn capabilities(&mut self) -> Result<Capabilities, Error>

The CAPABILITY command requests a listing of capabilities that the server supports. The server will include “IMAP4rev1” as one of the listed capabilities. See [Capabilities] for further details.

pub async fn expunge( &mut self, ) -> Result<impl Stream<Item = Result<u32, Error>> + Send, Error>

The EXPUNGE command permanently removes all messages that have [Flag::Deleted] set from the currently selected mailbox. The message sequence number of each message that is removed is returned.

pub async fn uid_expunge<S>( &mut self, uid_set: S, ) -> Result<impl Stream<Item = Result<u32, Error>> + Send, Error>
where S: AsRef<str>,

The UID EXPUNGE command permanently removes all messages that both have [Flag::Deleted] set and have a [Uid] that is included in the specified sequence set from the currently selected mailbox. If a message either does not have [Flag::Deleted] set or has a [Uid] that is not included in the specified sequence set, it is not affected.

This command is particularly useful for disconnected use clients. By using uid_expunge instead of [Self::expunge] when resynchronizing with the server, the client can ensure that it does not inadvertantly remove any messages that have been marked as [Flag::Deleted] by other clients between the time that the client was last connected and the time the client resynchronizes.

This command requires that the server supports RFC 4315 as indicated by the UIDPLUS capability (see [Session::capabilities]). If the server does not support the UIDPLUS capability, the client should fall back to using [Session::store] to temporarily remove [Flag::Deleted] from messages it does not want to remove, then invoking [Session::expunge]. Finally, the client should use [Session::store] to restore [Flag::Deleted] on the messages in which it was temporarily removed.

Alternatively, the client may fall back to using just [Session::expunge], risking the unintended removal of some messages.

pub async fn check(&mut self) -> Result<(), Error>

The CHECK command requests a checkpoint of the currently selected mailbox. A checkpoint refers to any implementation-dependent housekeeping associated with the mailbox (e.g., resolving the server’s in-memory state of the mailbox with the state on its disk) that is not normally executed as part of each command. A checkpoint MAY take a non-instantaneous amount of real time to complete. If a server implementation has no such housekeeping considerations, [Session::check] is equivalent to [Session::noop].

There is no guarantee that an EXISTS untagged response will happen as a result of CHECK. [Session::noop] SHOULD be used for new message polling.

pub async fn close(&mut self) -> Result<(), Error>

The CLOSE command permanently removes all messages that have [Flag::Deleted] set from the currently selected mailbox, and returns to the authenticated state from the selected state. No EXPUNGE responses are sent.

No messages are removed, and no error is given, if the mailbox is selected by [Session::examine] or is otherwise selected read-only.

Even if a mailbox is selected, [Session::select], [Session::examine], or [Session::logout] command MAY be issued without previously invoking [Session::close]. [Session::select], [Session::examine], and [Session::logout] implicitly close the currently selected mailbox without doing an expunge. However, when many messages are deleted, a CLOSE-LOGOUT or CLOSE-SELECT sequence is considerably faster than an EXPUNGE-LOGOUT or EXPUNGE-SELECT because no EXPUNGE responses (which the client would probably ignore) are sent.

pub async fn store<S1, S2>( &mut self, sequence_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
where S1: AsRef<str>, S2: AsRef<str>,

The STORE command alters data associated with a message in the mailbox. Normally, STORE will return the updated value of the data with an untagged FETCH response. A suffix of .SILENT in query prevents the untagged FETCH, and the server assumes that the client has determined the updated value itself or does not care about the updated value.

The currently defined data items that can be stored are:

  • FLAGS <flag list>:

    Replace the flags for the message (other than [Flag::Recent]) with the argument. The new value of the flags is returned as if a FETCH of those flags was done.

  • FLAGS.SILENT <flag list>: Equivalent to FLAGS, but without returning a new value.

  • +FLAGS <flag list>

    Add the argument to the flags for the message. The new value of the flags is returned as if a FETCH of those flags was done.

  • +FLAGS.SILENT <flag list>: Equivalent to +FLAGS, but without returning a new value.

  • -FLAGS <flag list>

    Remove the argument from the flags for the message. The new value of the flags is returned as if a FETCH of those flags was done.

  • -FLAGS.SILENT <flag list>: Equivalent to -FLAGS, but without returning a new value.

In all cases, <flag list> is a space-separated list enclosed in parentheses.

§Examples

Delete a message:

use async_imap::{types::Seq, Session, error::Result};
#[cfg(feature = "runtime-async-std")]
use async_std::net::TcpStream;
#[cfg(feature = "runtime-tokio")]
use tokio::net::TcpStream;
use futures::TryStreamExt;

async fn delete(seq: Seq, s: &mut Session<TcpStream>) -> Result<()> {
    let updates_stream = s.store(format!("{}", seq), "+FLAGS (\\Deleted)").await?;
    let _updates: Vec<_> = updates_stream.try_collect().await?;
    s.expunge().await?;
    Ok(())
}

pub async fn uid_store<S1, S2>( &mut self, uid_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
where S1: AsRef<str>, S2: AsRef<str>,

Equivalent to [Session::store], except that all identifiers in sequence_set are [Uid]s. See also the UID command.

pub async fn copy<S1, S2>( &mut self, sequence_set: S1, mailbox_name: S2, ) -> Result<(), Error>
where S1: AsRef<str>, S2: AsRef<str>,

The COPY command copies the specified message(s) to the end of the specified destination mailbox. The flags and internal date of the message(s) will generally be preserved, and [Flag::Recent] will generally be set, in the copy.

If the COPY command is unsuccessful for any reason, the server restores the destination mailbox to its state before the COPY attempt.

pub async fn uid_copy<S1, S2>( &mut self, uid_set: S1, mailbox_name: S2, ) -> Result<(), Error>
where S1: AsRef<str>, S2: AsRef<str>,

Equivalent to [Session::copy], except that all identifiers in sequence_set are [Uid]s. See also the UID command.

pub async fn mv<S1, S2>( &mut self, sequence_set: S1, mailbox_name: S2, ) -> Result<(), Error>
where S1: AsRef<str>, S2: AsRef<str>,

The MOVE command takes two arguments: a sequence set and a named mailbox. Each message included in the set is moved, rather than copied, from the selected (source) mailbox to the named (target) mailbox.

This means that a new message is created in the target mailbox with a new [Uid], the original message is removed from the source mailbox, and it appears to the client as a single action. This has the same effect for each message as this sequence:

  1. COPY
  2. STORE +FLAGS.SILENT \DELETED
  3. EXPUNGE

This command requires that the server supports RFC 6851 as indicated by the MOVE capability (see [Session::capabilities]).

Although the effect of the MOVE is the same as the preceding steps, the semantics are not identical: The intermediate states produced by those steps do not occur, and the response codes are different. In particular, though the COPY and EXPUNGE response codes will be returned, response codes for a store will not be generated and [Flag::Deleted] will not be set for any message.

Because a MOVE applies to a set of messages, it might fail partway through the set. Regardless of whether the command is successful in moving the entire set, each individual message will either be moved or unaffected. The server will leave each message in a state where it is in at least one of the source or target mailboxes (no message can be lost or orphaned). The server will generally not leave any message in both mailboxes (it would be bad for a partial failure to result in a bunch of duplicate messages). This is true even if the server returns with [Error::No].

pub async fn uid_mv<S1, S2>( &mut self, uid_set: S1, mailbox_name: S2, ) -> Result<(), Error>
where S1: AsRef<str>, S2: AsRef<str>,

Equivalent to [Session::copy], except that all identifiers in sequence_set are [Uid]s. See also the UID command and the semantics of MOVE and UID MOVE.

pub async fn list( &mut self, reference_name: Option<&str>, mailbox_pattern: Option<&str>, ) -> Result<impl Stream<Item = Result<Name, Error>> + Send, Error>

The LIST command returns a subset of names from the complete set of all names available to the client. It returns the name attributes, hierarchy delimiter, and name of each such name; see [Name] for more detail.

If reference_name is None (or ""), the currently selected mailbox is used. The returned mailbox names must match the supplied mailbox_pattern. A non-empty reference name argument is the name of a mailbox or a level of mailbox hierarchy, and indicates the context in which the mailbox name is interpreted.

If mailbox_pattern is None (or ""), it is a special request to return the hierarchy delimiter and the root name of the name given in the reference. The value returned as the root MAY be the empty string if the reference is non-rooted or is an empty string. In all cases, a hierarchy delimiter (or NIL if there is no hierarchy) is returned. This permits a client to get the hierarchy delimiter (or find out that the mailbox names are flat) even when no mailboxes by that name currently exist.

The reference and mailbox name arguments are interpreted into a canonical form that represents an unambiguous left-to-right hierarchy. The returned mailbox names will be in the interpreted form.

The character * is a wildcard, and matches zero or more characters at this position. The character % is similar to *, but it does not match a hierarchy delimiter. If the % wildcard is the last character of a mailbox name argument, matching levels of hierarchy are also returned. If these levels of hierarchy are not also selectable mailboxes, they are returned with [NameAttribute::NoSelect].

The special name INBOX is included if INBOX is supported by this server for this user and if the uppercase string INBOX matches the interpreted reference and mailbox name arguments with wildcards. The criteria for omitting INBOX is whether SELECT INBOX will return failure; it is not relevant whether the user’s real INBOX resides on this or some other server.

pub async fn lsub( &mut self, reference_name: Option<&str>, mailbox_pattern: Option<&str>, ) -> Result<impl Stream<Item = Result<Name, Error>> + Send, Error>

The LSUB command returns a subset of names from the set of names that the user has declared as being “active” or “subscribed”. The arguments to this method the same as for [Session::list].

The returned [Name]s MAY contain different mailbox flags from response to [Session::list]. If this should happen, the flags returned by [Session::list] are considered more authoritative.

A special situation occurs when invoking lsub with the % wildcard. Consider what happens if foo/bar (with a hierarchy delimiter of /) is subscribed but foo is not. A % wildcard to lsub must return foo, not foo/bar, and it will be flagged with [NameAttribute::NoSelect].

The server will not unilaterally remove an existing mailbox name from the subscription list even if a mailbox by that name no longer exists.

pub async fn status<S1, S2>( &mut self, mailbox_name: S1, data_items: S2, ) -> Result<Mailbox, Error>
where S1: AsRef<str>, S2: AsRef<str>,

The STATUS command requests the status of the indicated mailbox. It does not change the currently selected mailbox, nor does it affect the state of any messages in the queried mailbox (in particular, status will not cause messages to lose [Flag::Recent]).

status provides an alternative to opening a second [Session] and using [Session::examine] on a mailbox to query that mailbox’s status without deselecting the current mailbox in the first Session.

Unlike [Session::list], status is not guaranteed to be fast in its response. Under certain circumstances, it can be quite slow. In some implementations, the server is obliged to open the mailbox read-only internally to obtain certain status information. Also unlike [Session::list], status does not accept wildcards.

Note: status is intended to access the status of mailboxes other than the currently selected mailbox. Because status can cause the mailbox to be opened internally, and because this information is available by other means on the selected mailbox, status SHOULD NOT be used on the currently selected mailbox.

The STATUS command MUST NOT be used as a “check for new messages in the selected mailbox” operation (refer to sections 7, 7.3.1, and 7.3.2 for more information about the proper method for new message checking).

The currently defined status data items that can be requested are:

  • MESSAGES: The number of messages in the mailbox.
  • RECENT: The number of messages with [Flag::Recent] set.
  • UIDNEXT: The next [Uid] of the mailbox.
  • UIDVALIDITY: The unique identifier validity value of the mailbox (see [Uid]).
  • UNSEEN: The number of messages which do not have [Flag::Seen] set.

data_items is a space-separated list enclosed in parentheses.

pub async fn append( &mut self, mailbox: impl AsRef<str>, flags: Option<&str>, internaldate: Option<&str>, content: impl AsRef<[u8]>, ) -> Result<(), Error>

The APPEND command appends content as a new message to the end of the specified destination mailbox. This argument SHOULD be in the format of an RFC-2822 message.

Note: There MAY be exceptions, e.g., draft messages, in which required RFC-2822 header lines are omitted in the message literal argument to append. The full implications of doing so MUST be understood and carefully weighed.

If the append is unsuccessful for any reason, the mailbox is restored to its state before the append attempt; no partial appending will happen.

If the destination mailbox does not exist, the server returns an error, and does not automatically create the mailbox.

If the mailbox is currently selected, the normal new message actions will generally occur. Specifically, the server will generally notify the client immediately via an untagged EXISTS response. If the server does not do so, the client MAY issue a NOOP command (or failing that, a CHECK command) after one or more APPEND commands.

pub async fn search<S>(&mut self, query: S) -> Result<HashSet<u32>, Error>
where S: AsRef<str>,

The SEARCH command searches the mailbox for messages that match the given query. query consist of one or more search keys separated by spaces. The response from the server contains a listing of [Seq]s corresponding to those messages that match the searching criteria.

When multiple search keys are specified, the result is the intersection of all the messages that match those keys. Or, in other words, only messages that match all the keys. For example, the criteria

DELETED FROM "SMITH" SINCE 1-Feb-1994

refers to all deleted messages from Smith that were placed in the mailbox since February 1, 1994. A search key can also be a parenthesized list of one or more search keys (e.g., for use with the OR and NOT keys).

In all search keys that use strings, a message matches the key if the string is a substring of the field. The matching is case-insensitive.

Below is a selection of common search keys. The full list can be found in the specification of the SEARCH command.

  • NEW: Messages that have [Flag::Recent] set but not [Flag::Seen]. This is functionally equivalent to (RECENT UNSEEN).

  • OLD: Messages that do not have [Flag::Recent] set. This is functionally equivalent to NOT RECENT (as opposed to NOT NEW).

  • RECENT: Messages that have [Flag::Recent] set.

  • ANSWERED: Messages with [Flag::Answered] set.

  • DELETED: Messages with [Flag::Deleted] set.

  • DRAFT: Messages with [Flag::Draft] set.

  • FLAGGED: Messages with [Flag::Flagged] set.

  • SEEN: Messages that have [Flag::Seen] set.

  • <sequence set>: Messages with message sequence numbers corresponding to the specified message sequence number set.

  • UID <sequence set>: Messages with [Uid] corresponding to the specified unique identifier set. Sequence set ranges are permitted.

  • SUBJECT <string>: Messages that contain the specified string in the envelope structure’s SUBJECT field.

  • BODY <string>: Messages that contain the specified string in the body of the message.

  • FROM <string>: Messages that contain the specified string in the envelope structure’s FROM field.

  • TO <string>: Messages that contain the specified string in the envelope structure’s TO field.

  • NOT <search-key>: Messages that do not match the specified search key.

  • OR <search-key1> <search-key2>: Messages that match either search key.

  • BEFORE <date>: Messages whose internal date (disregarding time and timezone) is earlier than the specified date.

  • SINCE <date>: Messages whose internal date (disregarding time and timezone) is within or later than the specified date.

Equivalent to [Session::search], except that the returned identifiers are [Uid] instead of [Seq]. See also the UID command.

pub async fn get_quota(&mut self, quota_root: &str) -> Result<Quota, Error>

pub async fn get_quota_root( &mut self, mailbox_name: &str, ) -> Result<(Vec<QuotaRoot>, Vec<Quota>), Error>

pub async fn get_metadata( &mut self, mailbox_name: &str, options: &str, entry_specifier: &str, ) -> Result<Vec<Metadata>, Error>

pub async fn id( &mut self, identification: impl IntoIterator<Item = (&str, Option<&str>)>, ) -> Result<Option<HashMap<String, String>>, Error>

The ID command

identification is an iterable sequence of pairs such as ("name", Some("MyMailClient")).

pub async fn id_nil(&mut self) -> Result<Option<HashMap<String, String>>, Error>

Similar to id, but don’t identify ourselves.

Sends ID NIL command and returns server response.

pub async fn run_command_and_check_ok<S>( &mut self, command: S, ) -> Result<(), Error>
where S: AsRef<str>,

Runs a command and checks if it returns OK.

pub async fn run_command<S>(&mut self, command: S) -> Result<RequestId, Error>
where S: AsRef<str>,

Runs any command passed to it.

pub async fn run_command_untagged<S>(&mut self, command: S) -> Result<(), Error>
where S: AsRef<str>,

Runs an arbitrary command, without adding a tag to it.

pub async fn read_response(&mut self) -> Option<Result<ResponseData, Error>>

Read the next response on the connection.

Methods from Deref<Target = Connection<T>>§

pub async fn read_response(&mut self) -> Option<Result<ResponseData, Error>>

Read the next response on the connection.

pub async fn run_command_and_check_ok( &mut self, command: &str, unsolicited: Option<Sender<UnsolicitedResponse>>, ) -> Result<(), Error>

Execute a command and check that the next response is a matching done.

Trait Implementations§

source§

impl Debug for Session

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Session

source§

type Target = Session<Box<dyn SessionStream>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Session

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> MaybeSendSync for T