async_imap_lite/
session.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::mpsc;
3
4use crate::connection::{
5    AsRawFdOrSocket, Async, AsyncConnection, AsyncRead, AsyncWrite, TlsClientUpgrader,
6    UpgraderExtRefer,
7};
8use crate::imap::{parse::*, types::*, validate_str, Result};
9
10pub struct AsyncSession<AS, ASTU>
11where
12    AS: AsRawFdOrSocket,
13    Async<AS>: AsyncRead + AsyncWrite,
14    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
15    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
16{
17    conn: AsyncConnection<AS, ASTU>,
18    // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L53
19    unsolicited_responses_tx: mpsc::Sender<UnsolicitedResponse>,
20    // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L57
21    pub unsolicited_responses: mpsc::Receiver<UnsolicitedResponse>,
22}
23
24// ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L102-L108
25impl<AS, ASTU> Deref for AsyncSession<AS, ASTU>
26where
27    AS: AsRawFdOrSocket,
28    Async<AS>: AsyncRead + AsyncWrite,
29    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
30    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
31{
32    type Target = AsyncConnection<AS, ASTU>;
33
34    fn deref(&self) -> &AsyncConnection<AS, ASTU> {
35        &self.conn
36    }
37}
38
39// ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L110-L114
40impl<AS, ASTU> DerefMut for AsyncSession<AS, ASTU>
41where
42    AS: AsRawFdOrSocket,
43    Async<AS>: AsyncRead + AsyncWrite,
44    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
45    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
46{
47    fn deref_mut(&mut self) -> &mut AsyncConnection<AS, ASTU> {
48        &mut self.conn
49    }
50}
51
52impl<AS, ASTU> AsyncSession<AS, ASTU>
53where
54    AS: AsRawFdOrSocket,
55    Async<AS>: AsyncRead + AsyncWrite,
56    ASTU: TlsClientUpgrader<Async<AS>> + UpgraderExtRefer<Async<AS>> + Unpin,
57    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
58{
59    pub(crate) fn new(conn: AsyncConnection<AS, ASTU>) -> Self {
60        // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L435-L439
61        let (tx, rx) = mpsc::channel();
62        Self {
63            conn,
64            unsolicited_responses: rx,
65            unsolicited_responses_tx: tx,
66        }
67    }
68
69    // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L461-L468
70    pub async fn select<S: AsRef<str>>(&mut self, mailbox_name: S) -> Result<Mailbox> {
71        self.run_command_and_read_response(&format!(
72            "SELECT {}",
73            validate_str(mailbox_name.as_ref())?
74        ))
75        .await
76        .and_then(|lines| parse_mailbox(&lines[..], &mut self.unsolicited_responses_tx))
77    }
78
79    // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L540-L551
80    pub async fn fetch<S1, S2>(&mut self, sequence_set: S1, query: S2) -> ZeroCopyResult<Vec<Fetch>>
81    where
82        S1: AsRef<str>,
83        S2: AsRef<str>,
84    {
85        self.run_command_and_read_response(&format!(
86            "FETCH {} {}",
87            sequence_set.as_ref(),
88            query.as_ref()
89        ))
90        .await
91        .and_then(|lines| parse_fetches(lines, &mut self.unsolicited_responses_tx))
92    }
93}