Skip to main content

rusmes_core/
matcher.rs

1//! Matcher trait for filtering mail recipients
2
3use async_trait::async_trait;
4use rusmes_proto::{Mail, MailAddress};
5
6/// Matcher trait - filter recipients based on criteria
7#[async_trait]
8pub trait Matcher: Send + Sync {
9    /// Returns subset of recipients matching criteria
10    async fn match_mail(&self, mail: &Mail) -> anyhow::Result<Vec<MailAddress>>;
11
12    /// Matcher name for logging
13    fn name(&self) -> &str;
14}
15
16/// Match all recipients
17#[allow(dead_code)]
18pub struct AllMatcher;
19
20#[async_trait]
21impl Matcher for AllMatcher {
22    async fn match_mail(&self, mail: &Mail) -> anyhow::Result<Vec<MailAddress>> {
23        Ok(mail.recipients().to_vec())
24    }
25
26    fn name(&self) -> &str {
27        "All"
28    }
29}
30
31/// Match no recipients
32#[allow(dead_code)]
33pub struct NoneMatcher;
34
35#[async_trait]
36impl Matcher for NoneMatcher {
37    async fn match_mail(&self, _mail: &Mail) -> anyhow::Result<Vec<MailAddress>> {
38        Ok(Vec::new())
39    }
40
41    fn name(&self) -> &str {
42        "None"
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49    use bytes::Bytes;
50    use rusmes_proto::{HeaderMap, MessageBody, MimeMessage};
51
52    #[tokio::test]
53    async fn test_all_matcher() {
54        let recipients = vec![
55            "user1@example.com".parse().unwrap(),
56            "user2@example.com".parse().unwrap(),
57        ];
58        let message = MimeMessage::new(HeaderMap::new(), MessageBody::Small(Bytes::from("Test")));
59        let mail = Mail::new(None, recipients.clone(), message, None, None);
60
61        let matcher = AllMatcher;
62        let matched = matcher.match_mail(&mail).await.unwrap();
63        assert_eq!(matched.len(), 2);
64    }
65
66    #[tokio::test]
67    async fn test_none_matcher() {
68        let recipients = vec!["user@example.com".parse().unwrap()];
69        let message = MimeMessage::new(HeaderMap::new(), MessageBody::Small(Bytes::from("Test")));
70        let mail = Mail::new(None, recipients, message, None, None);
71
72        let matcher = NoneMatcher;
73        let matched = matcher.match_mail(&mail).await.unwrap();
74        assert_eq!(matched.len(), 0);
75    }
76}