imap_client/client/
mod.rs1pub mod tokio;
2pub mod verifier;
3
4use std::time::Duration;
5
6use imap_next::{
7 client::Options as ClientOptions,
8 imap_types::{auth::AuthMechanism, core::Vec1, response::Capability},
9};
10
11use crate::tasks::resolver::Resolver;
12
13pub struct Client {
14 resolver: Resolver,
15 capabilities: Vec1<Capability<'static>>,
16 idle_timeout: Duration,
17}
18
19impl Client {
20 pub fn new(opts: ClientOptions) -> Self {
21 let client = imap_next::client::Client::new(opts);
22 let resolver = Resolver::new(client);
23
24 Self {
25 resolver,
26 capabilities: Vec1::from(Capability::Imap4Rev1),
27 idle_timeout: Duration::from_secs(5 * 60), }
29 }
30
31 pub fn get_idle_timeout(&self) -> &Duration {
32 &self.idle_timeout
33 }
34
35 pub fn set_idle_timeout(&mut self, timeout: Duration) {
36 self.idle_timeout = timeout;
37 }
38
39 pub fn set_some_idle_timeout(&mut self, timeout: Option<Duration>) {
40 if let Some(timeout) = timeout {
41 self.set_idle_timeout(timeout)
42 }
43 }
44
45 pub fn with_idle_timeout(mut self, timeout: Duration) -> Self {
46 self.set_idle_timeout(timeout);
47 self
48 }
49
50 pub fn with_some_idle_timeout(mut self, timeout: Option<Duration>) -> Self {
51 self.set_some_idle_timeout(timeout);
52 self
53 }
54
55 pub fn capabilities(&self) -> &Vec1<Capability<'static>> {
62 &self.capabilities
63 }
64
65 pub fn capabilities_iter(&self) -> impl Iterator<Item = &Capability<'static>> + '_ {
70 self.capabilities().as_ref().iter()
71 }
72
73 pub fn supported_auth_mechanisms(&self) -> impl Iterator<Item = &AuthMechanism<'static>> + '_ {
75 self.capabilities_iter().filter_map(|capability| {
76 if let Capability::Auth(mechanism) = capability {
77 Some(mechanism)
78 } else {
79 None
80 }
81 })
82 }
83
84 pub fn supports_auth_mechanism(&self, mechanism: AuthMechanism<'static>) -> bool {
87 self.capabilities_iter().any(|capability| {
88 if let Capability::Auth(m) = capability {
89 m == &mechanism
90 } else {
91 false
92 }
93 })
94 }
95
96 pub fn login_supported(&self) -> bool {
98 !self
99 .capabilities_iter()
100 .any(|c| matches!(c, Capability::LoginDisabled))
101 }
102
103 pub fn ext_enable_supported(&self) -> bool {
106 self.capabilities_iter()
107 .any(|c| matches!(c, Capability::Enable))
108 }
109
110 pub fn ext_sasl_ir_supported(&self) -> bool {
113 self.capabilities_iter()
114 .any(|c| matches!(c, Capability::SaslIr))
115 }
116
117 pub fn ext_id_supported(&self) -> bool {
120 self.capabilities_iter()
121 .any(|c| matches!(c, Capability::Id))
122 }
123
124 pub fn ext_uidplus_supported(&self) -> bool {
127 self.capabilities_iter()
128 .any(|c| matches!(c, Capability::UidPlus))
129 }
130
131 pub fn ext_sort_supported(&self) -> bool {
134 self.capabilities_iter()
135 .any(|c| matches!(c, Capability::Sort(_)))
136 }
137
138 pub fn ext_thread_supported(&self) -> bool {
141 self.capabilities_iter()
142 .any(|c| matches!(c, Capability::Thread(_)))
143 }
144
145 pub fn ext_idle_supported(&self) -> bool {
148 self.capabilities_iter()
149 .any(|c| matches!(c, Capability::Idle))
150 }
151
152 pub fn ext_binary_supported(&self) -> bool {
155 self.capabilities_iter()
156 .any(|c| matches!(c, Capability::Binary))
157 }
158
159 pub fn ext_move_supported(&self) -> bool {
162 self.capabilities_iter()
163 .any(|c| matches!(c, Capability::Move))
164 }
165}