async_imap_lite/
client.rs1use 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
21impl<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
36impl<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
49macro_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 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}