async_imap_lite/
client.rs

1use std::ops::{Deref, DerefMut};
2use std::result;
3
4use crate::connection::{
5    AsRawFdOrSocket, Async, AsyncConnection, AsyncRead, AsyncWrite, TlsClientUpgrader,
6    UpgraderExtRefer,
7};
8use crate::imap::{validate_str, Error};
9use crate::session::AsyncSession;
10
11pub struct AsyncClient<AS, ASTU>
12where
13    AS: AsRawFdOrSocket,
14    Async<AS>: AsyncRead + AsyncWrite,
15    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
16    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
17{
18    conn: AsyncConnection<AS, ASTU>,
19}
20
21// ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L88-L94
22impl<AS, ASTU> Deref for AsyncClient<AS, ASTU>
23where
24    AS: AsRawFdOrSocket,
25    Async<AS>: AsyncRead + AsyncWrite,
26    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
27    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
28{
29    type Target = AsyncConnection<AS, ASTU>;
30
31    fn deref(&self) -> &AsyncConnection<AS, ASTU> {
32        &self.conn
33    }
34}
35
36// ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L96-L100
37impl<AS, ASTU> DerefMut for AsyncClient<AS, ASTU>
38where
39    AS: AsRawFdOrSocket,
40    Async<AS>: AsyncRead + AsyncWrite,
41    ASTU: TlsClientUpgrader<Async<AS>> + Unpin,
42    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
43{
44    fn deref_mut(&mut self) -> &mut AsyncConnection<AS, ASTU> {
45        &mut self.conn
46    }
47}
48
49// ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L226-L233
50macro_rules! ok_or_unauth_client_err {
51    ($r:expr, $self:expr) => {
52        match $r {
53            Ok(o) => o,
54            Err(e) => return Err((e, $self)),
55        }
56    };
57}
58
59impl<AS, ASTU> AsyncClient<AS, ASTU>
60where
61    AS: AsRawFdOrSocket,
62    Async<AS>: AsyncRead + AsyncWrite,
63    ASTU: TlsClientUpgrader<Async<AS>> + UpgraderExtRefer<Async<AS>> + Unpin,
64    ASTU::Output: AsyncRead + AsyncWrite + Unpin,
65{
66    pub(crate) fn new(conn: AsyncConnection<AS, ASTU>) -> Self {
67        Self { conn }
68    }
69
70    // ref https://github.com/jonhoo/rust-imap/blob/v2.2.0/src/client.rs#L307-L320
71    pub async fn login<U: AsRef<str>, P: AsRef<str>>(
72        mut self,
73        username: U,
74        password: P,
75    ) -> result::Result<AsyncSession<AS, ASTU>, (Error, Self)> {
76        let u = ok_or_unauth_client_err!(validate_str(username.as_ref()), self);
77        let p = ok_or_unauth_client_err!(validate_str(password.as_ref()), self);
78        ok_or_unauth_client_err!(
79            self.run_command_and_check_ok(&format!("LOGIN {} {}", u, p))
80                .await,
81            self
82        );
83
84        Ok(AsyncSession::new(self.conn))
85    }
86}