postfix_log_parser/events/
sendmail.rs

1//! Sendmail兼容接口模块
2//!
3//! 处理Postfix sendmail兼容命令的事件,包括命令行工具的使用错误和兼容性问题
4
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8/// Sendmail兼容接口事件
9///
10/// 记录通过Postfix的sendmail兼容接口产生的事件
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct SendmailEvent {
13    /// 事件发生时间戳(原始字符串格式)
14    /// 保持原始时间格式,如"Apr 24 17:20:55"
15    pub timestamp: String,
16
17    /// 进程ID(字符串格式)
18    /// sendmail兼容命令的进程标识符
19    pub process_id: String,
20
21    /// 事件类型(通常为致命使用错误)
22    pub event_type: SendmailEventType,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
26pub enum SendmailEventType {
27    /// Fatal usage error
28    FatalUsageError { message: String },
29}
30
31impl fmt::Display for SendmailEvent {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        write!(
34            f,
35            "[{}] sendmail[{}]: {}",
36            self.timestamp, self.process_id, self.event_type
37        )
38    }
39}
40
41impl fmt::Display for SendmailEventType {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        match self {
44            SendmailEventType::FatalUsageError { message } => {
45                write!(f, "Fatal usage error: {}", message)
46            }
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_fatal_usage_error_event() {
57        let event = SendmailEvent {
58            timestamp: "Apr 24 17:20:55".to_string(),
59            process_id: "180".to_string(),
60            event_type: SendmailEventType::FatalUsageError {
61                message: "usage: mailq [options]".to_string(),
62            },
63        };
64
65        assert_eq!(event.process_id, "180");
66
67        let SendmailEventType::FatalUsageError { message } = &event.event_type;
68        assert_eq!(message, "usage: mailq [options]");
69    }
70
71    #[test]
72    fn test_event_serialization() {
73        let event = SendmailEvent {
74            timestamp: "Apr 24 17:20:55".to_string(),
75            process_id: "180".to_string(),
76            event_type: SendmailEventType::FatalUsageError {
77                message: "usage: mailq [options]".to_string(),
78            },
79        };
80
81        let serialized = serde_json::to_string(&event).unwrap();
82        let deserialized: SendmailEvent = serde_json::from_str(&serialized).unwrap();
83        assert_eq!(event, deserialized);
84    }
85
86    #[test]
87    fn test_event_display() {
88        let event = SendmailEvent {
89            timestamp: "Apr 24 17:20:55".to_string(),
90            process_id: "180".to_string(),
91            event_type: SendmailEventType::FatalUsageError {
92                message: "usage: mailq [options]".to_string(),
93            },
94        };
95
96        let display = format!("{}", event);
97        assert!(display.contains("sendmail[180]"));
98        assert!(display.contains("Fatal usage error"));
99        assert!(display.contains("mailq [options]"));
100    }
101
102    #[test]
103    fn test_different_process_ids() {
104        let process_ids = ["180", "187", "208", "216", "223", "230"];
105
106        for pid in process_ids {
107            let event = SendmailEvent {
108                timestamp: "Apr 24 17:20:55".to_string(),
109                process_id: pid.to_string(),
110                event_type: SendmailEventType::FatalUsageError {
111                    message: "usage: mailq [options]".to_string(),
112                },
113            };
114
115            assert_eq!(event.process_id, pid);
116        }
117    }
118
119    #[test]
120    fn test_event_equality() {
121        let event1 = SendmailEvent {
122            timestamp: "Apr 24 17:20:55".to_string(),
123            process_id: "180".to_string(),
124            event_type: SendmailEventType::FatalUsageError {
125                message: "usage: mailq [options]".to_string(),
126            },
127        };
128
129        let event2 = SendmailEvent {
130            timestamp: "Apr 24 17:20:55".to_string(),
131            process_id: "180".to_string(),
132            event_type: SendmailEventType::FatalUsageError {
133                message: "usage: mailq [options]".to_string(),
134            },
135        };
136
137        assert_eq!(event1, event2);
138    }
139}