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
impl Session
sourceasync fn fetch_single_msg(
&mut self,
context: &Context,
folder: &str,
uidvalidity: u32,
uid: u32,
rfc724_mid: String,
) -> Result<()>
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
impl Session
sourcepub(super) async fn maybe_close_folder(
&mut self,
context: &Context,
) -> Result<()>
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
sourceasync fn select_folder(
&mut self,
context: &Context,
folder: &str,
) -> Result<NewlySelected, Error>
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.
sourcepub(super) async fn select_or_create_folder(
&mut self,
context: &Context,
folder: &str,
) -> Result<NewlySelected>
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.
sourcepub(crate) async fn select_with_uidvalidity(
&mut self,
context: &Context,
folder: &str,
) -> Result<(), Error>
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
impl Session
pub(crate) fn new( inner: ImapSession<Box<dyn SessionStream>>, capabilities: Capabilities, ) -> Self
pub fn can_idle(&self) -> bool
pub fn can_move(&self) -> bool
pub fn can_check_quota(&self) -> bool
pub fn can_condstore(&self) -> bool
pub fn can_metadata(&self) -> bool
pub fn can_push(&self) -> bool
pub fn is_chatmail(&self) -> bool
sourcepub async fn list_folders(&mut self) -> Result<Vec<Name>>
pub async fn list_folders(&mut self) -> Result<Vec<Name>>
Returns the names of all folders on the IMAP server.
sourcepub(crate) async fn prefetch(
&mut self,
uid_next: u32,
) -> Result<Vec<(u32, Fetch)>>
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).
sourcepub(crate) async fn prefetch_existing_msgs(
&mut self,
) -> Result<Vec<(u32, Fetch)>>
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
impl Session
sourcepub(crate) async fn resync_folders(&mut self, context: &Context) -> Result<()>
pub(crate) async fn resync_folders(&mut self, context: &Context) -> Result<()>
Synchronizes UIDs for all folders.
sourcepub(crate) async fn resync_folder_uids(
&mut self,
context: &Context,
folder: &str,
folder_meaning: FolderMeaning,
) -> Result<()>
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.
sourceasync fn delete_message_batch(
&mut self,
context: &Context,
uid_set: &str,
row_ids: Vec<i64>,
) -> Result<()>
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.
sourceasync fn move_message_batch(
&mut self,
context: &Context,
set: &str,
row_ids: Vec<i64>,
target: &str,
) -> Result<()>
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.
sourceasync fn move_delete_messages(
&mut self,
context: &Context,
folder: &str,
) -> Result<()>
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.
sourcepub(crate) async fn send_sync_msgs(
&mut self,
context: &Context,
folder: &str,
) -> Result<()>
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.
sourcepub(crate) async fn store_seen_flags_on_imap(
&mut self,
context: &Context,
) -> Result<()>
pub(crate) async fn store_seen_flags_on_imap( &mut self, context: &Context, ) -> Result<()>
Stores pending \Seen
flags for messages in imap_markseen
table.
sourcepub(crate) async fn sync_seen_flags(
&mut self,
context: &Context,
folder: &str,
) -> Result<()>
pub(crate) async fn sync_seen_flags( &mut self, context: &Context, folder: &str, ) -> Result<()>
Synchronizes \Seen
flags using CONDSTORE
extension.
sourcepub async fn get_all_recipients(
&mut self,
context: &Context,
) -> Result<Vec<SingleInfo>>
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.
sourcepub(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>)>
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.
sourcepub(crate) async fn fetch_metadata(&mut self, context: &Context) -> Result<()>
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.
sourcepub(crate) async fn register_token(&mut self, context: &Context) -> Result<()>
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
impl Session
sourceasync fn add_flag_finalized_with_set(
&mut self,
uid_set: &str,
flag: &str,
) -> Result<()>
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.
sourceasync fn configure_mvbox<'a>(
&mut self,
context: &Context,
folders: &[&'a str],
create_mvbox: bool,
) -> Result<Option<&'a str>>
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
impl Session
sourcefn drain_unsolicited_responses(&self, context: &Context) -> Result<bool>
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>
pub async fn select<S>(&mut self, mailbox_name: S) -> Result<Mailbox, Error>
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>
pub async fn select_condstore<S>( &mut self, mailbox_name: S, ) -> Result<Mailbox, Error>
Selects a mailbox with (CONDSTORE)
parameter as defined in
RFC 7162.
pub async fn examine<S>(&mut self, mailbox_name: S) -> Result<Mailbox, Error>
pub async fn examine<S>(&mut self, mailbox_name: S) -> Result<Mailbox, Error>
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>
pub async fn fetch<S1, S2>( &mut self, sequence_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
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
, andTEXT
. An empty section specification (i.e.,BODY[]
) refers to the entire message, including the header.The
HEADER
,HEADER.FIELDS
, andHEADER.FIELDS.NOT
part specifiers refer to the RFC-2822 header of the message or of an encapsulated MIME-IMT MESSAGE/RFC822 message.HEADER.FIELDS
andHEADER.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 byHEADER.FIELDS
contains only those header fields with a field-name that matches one of the names in the list; similarly, the subset returned byHEADER.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 whenBODY
is fetched; if this causes the flags to change, they will generally be included as part of theFETCH
responses. -
BODY.PEEK[<section>]
: An alternate form ofBODY[<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 toBODY[]
. -
RFC822.HEADER
: Functionally equivalent toBODY.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>
pub async fn uid_fetch<S1, S2>( &mut self, uid_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send + Unpin, Error>
Equivalent to [Session::fetch
], except that all identifiers in uid_set
are
[Uid
]s. See also the UID
command.
pub async fn logout(&mut self) -> Result<(), Error>
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>
pub async fn create<S>(&mut self, mailbox_name: S) -> Result<(), Error>
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>
pub async fn delete<S>(&mut self, mailbox_name: S) -> Result<(), Error>
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>
pub async fn rename<S1, S2>(&mut self, from: S1, to: S2) -> Result<(), Error>
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>
pub async fn subscribe<S>(&mut self, mailbox: S) -> Result<(), Error>
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>
pub async fn unsubscribe<S>(&mut self, mailbox: S) -> Result<(), Error>
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>
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>
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>
pub async fn uid_expunge<S>( &mut self, uid_set: S, ) -> Result<impl Stream<Item = Result<u32, Error>> + Send, Error>
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>
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>
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>
pub async fn store<S1, S2>( &mut self, sequence_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
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 aFETCH
of those flags was done. -
FLAGS.SILENT <flag list>
: Equivalent toFLAGS
, 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>
pub async fn uid_store<S1, S2>( &mut self, uid_set: S1, query: S2, ) -> Result<impl Stream<Item = Result<Fetch, Error>> + Send, Error>
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>
pub async fn copy<S1, S2>( &mut self, sequence_set: S1, mailbox_name: S2, ) -> Result<(), Error>
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>
pub async fn uid_copy<S1, S2>( &mut self, uid_set: S1, mailbox_name: S2, ) -> Result<(), Error>
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>
pub async fn mv<S1, S2>( &mut self, sequence_set: S1, mailbox_name: S2, ) -> Result<(), Error>
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:
- COPY
- STORE +FLAGS.SILENT \DELETED
- 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>
pub async fn uid_mv<S1, S2>( &mut self, uid_set: S1, mailbox_name: S2, ) -> Result<(), Error>
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>
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>
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>
pub async fn status<S1, S2>( &mut self, mailbox_name: S1, data_items: S2, ) -> Result<Mailbox, Error>
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. Becausestatus
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>
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>
pub async fn search<S>(&mut self, query: S) -> Result<HashSet<u32>, Error>
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 toNOT RECENT
(as opposed toNOT 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’sSUBJECT
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’sFROM
field. -
TO <string>
: Messages that contain the specified string in the envelope structure’sTO
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.
pub async fn uid_search<S>(&mut self, query: S) -> Result<HashSet<u32>, Error>
pub async fn uid_search<S>(&mut self, query: S) -> Result<HashSet<u32>, Error>
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(&mut self, quota_root: &str) -> Result<Quota, Error>
The GETQUOTA
command
pub async fn get_quota_root(
&mut self,
mailbox_name: &str,
) -> Result<(Vec<QuotaRoot>, Vec<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 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>
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>
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>
pub async fn run_command_and_check_ok<S>( &mut self, command: S, ) -> Result<(), Error>
Runs a command and checks if it returns OK.
pub async fn run_command<S>(&mut self, command: S) -> Result<RequestId, Error>
pub async fn run_command<S>(&mut self, command: S) -> Result<RequestId, Error>
Runs any command passed to it.
pub async fn run_command_untagged<S>(&mut self, command: S) -> Result<(), Error>
pub async fn run_command_untagged<S>(&mut self, command: S) -> Result<(), Error>
Runs an arbitrary command, without adding a tag to it.
pub async fn read_response(&mut self) -> Option<Result<ResponseData, Error>>
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>>
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>
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§
Auto Trait Implementations§
impl Freeze for Session
impl !RefUnwindSafe for Session
impl Send for Session
impl Sync for Session
impl Unpin for Session
impl !UnwindSafe for Session
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.