postfix_log_parser/events/
pickup.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5pub struct PickupEvent {
6    pub timestamp: DateTime<Utc>,
7    pub pid: Option<u32>,
8    pub event_type: PickupEventType,
9}
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub enum PickupEventType {
13    /// 配置覆盖警告
14    ConfigOverrideWarning {
15        file_path: String,
16        line_number: u32,
17        parameter_name: String,
18        parameter_value: String,
19    },
20    /// 邮件拾取事件
21    MailPickup {
22        queue_id: String,
23        uid: u32,
24        sender: String,
25    },
26}
27
28impl PickupEvent {
29    pub fn new(timestamp: DateTime<Utc>, pid: Option<u32>, event_type: PickupEventType) -> Self {
30        Self {
31            timestamp,
32            pid,
33            event_type,
34        }
35    }
36
37    /// 创建配置覆盖警告事件
38    pub fn config_override_warning(
39        timestamp: DateTime<Utc>,
40        pid: Option<u32>,
41        file_path: String,
42        line_number: u32,
43        parameter_name: String,
44        parameter_value: String,
45    ) -> Self {
46        Self::new(
47            timestamp,
48            pid,
49            PickupEventType::ConfigOverrideWarning {
50                file_path,
51                line_number,
52                parameter_name,
53                parameter_value,
54            },
55        )
56    }
57
58    /// 创建邮件拾取事件
59    pub fn mail_pickup(
60        timestamp: DateTime<Utc>,
61        pid: Option<u32>,
62        queue_id: String,
63        uid: u32,
64        sender: String,
65    ) -> Self {
66        Self::new(
67            timestamp,
68            pid,
69            PickupEventType::MailPickup {
70                queue_id,
71                uid,
72                sender,
73            },
74        )
75    }
76
77    /// 获取事件严重性
78    pub fn severity(&self) -> &'static str {
79        match &self.event_type {
80            PickupEventType::ConfigOverrideWarning { .. } => "warning",
81            PickupEventType::MailPickup { .. } => "info",
82        }
83    }
84
85    /// 获取参数名称(仅配置覆盖警告)
86    pub fn parameter_name(&self) -> Option<&str> {
87        match &self.event_type {
88            PickupEventType::ConfigOverrideWarning { parameter_name, .. } => Some(parameter_name),
89            _ => None,
90        }
91    }
92
93    /// 获取队列ID(仅邮件拾取事件)
94    pub fn queue_id(&self) -> Option<&str> {
95        match &self.event_type {
96            PickupEventType::MailPickup { queue_id, .. } => Some(queue_id),
97            _ => None,
98        }
99    }
100
101    /// 获取发件人(仅邮件拾取事件)
102    pub fn sender(&self) -> Option<&str> {
103        match &self.event_type {
104            PickupEventType::MailPickup { sender, .. } => Some(sender),
105            _ => None,
106        }
107    }
108
109    /// 获取UID(仅邮件拾取事件)
110    pub fn uid(&self) -> Option<u32> {
111        match &self.event_type {
112            PickupEventType::MailPickup { uid, .. } => Some(*uid),
113            _ => None,
114        }
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121    use chrono::Utc;
122
123    #[test]
124    fn test_config_override_warning_event() {
125        let timestamp = Utc::now();
126        let event = PickupEvent::config_override_warning(
127            timestamp,
128            Some(76),
129            "/etc/postfix/main.cf".to_string(),
130            820,
131            "smtpd_recipient_restrictions".to_string(),
132            "check_client_access pcre:/etc/postfix/filter_trusted".to_string(),
133        );
134
135        assert_eq!(event.timestamp, timestamp);
136        assert_eq!(event.pid, Some(76));
137        assert_eq!(event.severity(), "warning");
138        assert_eq!(event.parameter_name(), Some("smtpd_recipient_restrictions"));
139        assert_eq!(event.queue_id(), None);
140        assert_eq!(event.sender(), None);
141        assert_eq!(event.uid(), None);
142
143        match event.event_type {
144            PickupEventType::ConfigOverrideWarning {
145                file_path,
146                line_number,
147                parameter_name,
148                parameter_value,
149            } => {
150                assert_eq!(file_path, "/etc/postfix/main.cf");
151                assert_eq!(line_number, 820);
152                assert_eq!(parameter_name, "smtpd_recipient_restrictions");
153                assert!(parameter_value.contains("check_client_access"));
154            }
155            _ => panic!("Expected ConfigOverrideWarning"),
156        }
157    }
158
159    #[test]
160    fn test_mail_pickup_event() {
161        let timestamp = Utc::now();
162        let event = PickupEvent::mail_pickup(
163            timestamp,
164            Some(76),
165            "226751E20F00".to_string(),
166            0,
167            "<root>".to_string(),
168        );
169
170        assert_eq!(event.timestamp, timestamp);
171        assert_eq!(event.pid, Some(76));
172        assert_eq!(event.severity(), "info");
173        assert_eq!(event.parameter_name(), None);
174        assert_eq!(event.queue_id(), Some("226751E20F00"));
175        assert_eq!(event.sender(), Some("<root>"));
176        assert_eq!(event.uid(), Some(0));
177
178        match event.event_type {
179            PickupEventType::MailPickup {
180                queue_id,
181                uid,
182                sender,
183            } => {
184                assert_eq!(queue_id, "226751E20F00");
185                assert_eq!(uid, 0);
186                assert_eq!(sender, "<root>");
187            }
188            _ => panic!("Expected MailPickup"),
189        }
190    }
191
192    #[test]
193    fn test_event_equality() {
194        let timestamp = Utc::now();
195        let event1 = PickupEvent::config_override_warning(
196            timestamp,
197            Some(76),
198            "/etc/postfix/main.cf".to_string(),
199            806,
200            "smtpd_client_message_rate_limit".to_string(),
201            "0".to_string(),
202        );
203
204        let event2 = PickupEvent::config_override_warning(
205            timestamp,
206            Some(76),
207            "/etc/postfix/main.cf".to_string(),
208            806,
209            "smtpd_client_message_rate_limit".to_string(),
210            "0".to_string(),
211        );
212
213        assert_eq!(event1, event2);
214    }
215}