1use std::{error::Error, fmt::Display, future::Future, pin::Pin};
8
9pub type HandlerResult<T> = Result<T, HandlerError>;
11
12pub type HandlerFuture<'a> = Pin<Box<dyn Future<Output = HandlerResult<()>> + Send + 'a>>;
14
15#[derive(Debug)]
17pub enum HandlerError {
18 Storage(String),
20 Connection(String),
22 Serialization(String),
24 Rejected(String),
26}
27
28impl Display for HandlerError {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 HandlerError::Storage(msg) => write!(f, "Storage error: {msg}"),
32 HandlerError::Connection(msg) => write!(f, "Connection error: {msg}"),
33 HandlerError::Serialization(msg) => write!(f, "Serialization error: {msg}"),
34 HandlerError::Rejected(msg) => write!(f, "Rejected: {msg}"),
35 }
36 }
37}
38
39impl Error for HandlerError {}
40
41pub trait MessageHandler: Send + Sync {
47 fn handle<'a>(&'a self, message: &'a crate::EmailMessage) -> HandlerFuture<'a>;
49
50 fn name(&self) -> &str;
52
53 fn reject_reply(&self) -> Option<(u16, String)> {
56 None
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_handler_error_display() {
66 assert_eq!(
67 HandlerError::Storage("test".to_string()).to_string(),
68 "Storage error: test"
69 );
70 assert_eq!(
71 HandlerError::Connection("test".to_string()).to_string(),
72 "Connection error: test"
73 );
74 assert_eq!(
75 HandlerError::Serialization("test".to_string()).to_string(),
76 "Serialization error: test"
77 );
78 assert_eq!(
79 HandlerError::Rejected("Relay access denied".to_string()).to_string(),
80 "Rejected: Relay access denied"
81 );
82 }
83}