1use std::fmt::Debug;
2
3#[cfg(feature = "serdex")]
4use serde::{Deserialize, Serialize};
5
6#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Greeting {
11 pub code: Vec<String>,
13 pub comment: String,
14 pub timestamp: Option<String>,
15}
16
17#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct SingleLine {
20 pub code: Vec<String>,
22 pub comment: String,
23}
24
25#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct MultiLine<T>
28where
29 T: Debug + Clone + PartialEq + Eq,
31{
32 pub head: SingleLine,
33 pub body: Vec<T>,
34}
35
36#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub enum Response<O, E>
39where
40 O: Debug + Clone + PartialEq + Eq,
42 E: Debug + Clone + PartialEq + Eq,
43{
44 Ok(O),
45 Err(E),
46}
47
48impl<O, E> Response<O, E>
49where
50 O: Debug + Clone + PartialEq + Eq,
52 E: Debug + Clone + PartialEq + Eq,
53{
54 pub fn unwrap(self) -> O {
55 match self {
56 Response::Ok(o) => o,
57 Response::Err(e) => panic!("{:?}", e),
58 }
59 }
60}
61
62#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub struct DropListing {
65 pub message_count: u32,
66 pub maildrop_size: u32,
67}
68
69#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
70#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct ScanListing {
72 pub message_id: u32,
73 pub message_size: u32,
74}
75
76#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct UniqueIdListing {
79 pub message_id: u32,
80 pub message_uid: String,
81}
82
83#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct LanguageListing {
86 pub tag: String, pub description: String,
88}
89
90#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub enum Capability {
93 Top,
95 User,
96 Sasl {
97 mechanisms: Vec<String>, },
99 RespCodes,
100 LoginDelay {
101 minimum_seconds: u32,
102 per_user: bool,
103 },
104 Pipelining,
105 Expire {
106 policy: ExpirePolicy,
107 per_user: bool,
108 },
109 Uidl,
110 Implementation {
111 text: String,
112 },
113 Stls,
115 AuthRespCode,
117 Utf8 {
119 in_credentials: bool,
120 },
121 Lang,
122 Other {
124 tag: String,
125 parameters: Vec<String>,
126 },
127}
128
129impl ToString for Capability {
130 fn to_string(&self) -> String {
131 use Capability::*;
132
133 match self {
134 Top => "TOP".into(),
135 User => "USER".into(),
136 Sasl { mechanisms } => {
137 format!("SASL {}", mechanisms.join(" "))
138 }
139 RespCodes => "RESP-CODES".into(),
140 LoginDelay {
141 minimum_seconds,
142 per_user,
143 } => {
144 let mut out = format!("LOGIN-DELAY {}", minimum_seconds);
145 if *per_user {
146 out.push_str(" USER");
147 }
148 out
149 }
150 Pipelining => "PIPELINING".into(),
151 Expire { policy, per_user } => {
152 let mut out = format!("EXPIRE {}", policy.to_string());
153 if *per_user {
154 out.push_str(" USER");
155 }
156 out
157 }
158 Uidl => "UIDL".into(),
159 Implementation { text: tag } => format!("IMPLEMENTATION {}", tag),
160 Stls => "STLS".into(),
161 AuthRespCode => "AUTH-RESP-CODE".into(),
162 Utf8 { in_credentials } => {
163 if *in_credentials {
164 "UTF8 USER".into()
165 } else {
166 "UTF8".into()
167 }
168 }
169 Lang => "LANG".into(),
170 Other { tag, parameters } => format!("{} {}", tag, parameters.join(" ")),
171 }
172 }
173}
174
175#[cfg_attr(feature = "serdex", derive(Serialize, Deserialize))]
176#[derive(Debug, Clone, PartialEq, Eq)]
177pub enum ExpirePolicy {
178 Never,
179 MinimumDays(u32),
180}
181
182impl ToString for ExpirePolicy {
183 fn to_string(&self) -> String {
184 match self {
185 ExpirePolicy::Never => "NEVER".into(),
186 ExpirePolicy::MinimumDays(days) => days.to_string(),
187 }
188 }
189}