postfix_log_parser/utils/
queue_id.rs

1use lazy_static::lazy_static;
2use regex::Regex;
3
4lazy_static! {
5    /// 统一的队列ID正则表达式
6    /// 新格式: 10-20个字符的字母数字组合,例如: 4bG4VR5zTgz6pqsd, 4bG5rK2jJfz6pr1t
7    pub static ref QUEUE_ID_REGEX: Regex = Regex::new(r"^([0-9A-Za-z]{10,20}):").unwrap();
8
9    /// 完整的队列ID捕获正则表达式,用于替换现有组件中的模式
10    pub static ref QUEUE_ID_PATTERN: &'static str = r"([0-9A-Za-z]{10,20})";
11}
12
13/// 从消息中提取队列ID
14///
15/// # 参数
16/// * `message` - 包含队列ID的消息字符串
17///
18/// # 返回
19/// * `Some(String)` - 如果找到队列ID
20/// * `None` - 如果没有找到队列ID
21pub fn extract_queue_id(message: &str) -> Option<String> {
22    QUEUE_ID_REGEX
23        .captures(message)
24        .and_then(|captures| captures.get(1))
25        .map(|m| m.as_str().to_string())
26}
27
28/// 创建包含队列ID的正则表达式模式
29///
30/// # 参数
31/// * `pattern` - 包含`{QUEUE_ID}`占位符的正则表达式模式
32///
33/// # 返回
34/// * 替换了占位符的完整正则表达式字符串
35///
36/// # 示例
37/// ```
38/// use postfix_log_parser::utils::queue_id::create_queue_id_pattern;
39/// let pattern = create_queue_id_pattern(r"^{QUEUE_ID}: to=<([^>]+)>");
40/// assert_eq!(pattern, r"^([0-9A-Za-z]{10,20}): to=<([^>]+)>");
41/// ```
42pub fn create_queue_id_pattern(pattern: &str) -> String {
43    pattern.replace("{QUEUE_ID}", *QUEUE_ID_PATTERN)
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_extract_queue_id_new_format() {
52        let message = "4bG4VR5zTgz6pqsd: client=localhost[127.0.0.1]:60166";
53        let result = extract_queue_id(message);
54        assert_eq!(result, Some("4bG4VR5zTgz6pqsd".to_string()));
55    }
56
57    #[test]
58    fn test_extract_queue_id_various_formats() {
59        let test_cases = vec![
60            (
61                "4bG5rK2jJfz6pr1t: message-id=<test@example.com>",
62                Some("4bG5rK2jJfz6pr1t".to_string()),
63            ),
64            (
65                "4bG6s970Nhz6qsfY: to=<user@example.com>",
66                Some("4bG6s970Nhz6qsfY".to_string()),
67            ),
68            (
69                "4bG6sC3LJbz6qsfc: from=<sender@example.com>",
70                Some("4bG6sC3LJbz6qsfc".to_string()),
71            ),
72            ("no queue id in this message", None),
73            ("ABC123: too short", None),
74            ("4bG5rK2jJfz6pr1tTooLong: too long", None),
75        ];
76
77        for (input, expected) in test_cases {
78            assert_eq!(
79                extract_queue_id(input),
80                expected,
81                "Failed for input: {}",
82                input
83            );
84        }
85    }
86
87    #[test]
88    fn test_create_queue_id_pattern() {
89        let pattern = create_queue_id_pattern(r"^{QUEUE_ID}: to=<([^>]+)>");
90        assert_eq!(pattern, r"^([0-9A-Za-z]{10,20}): to=<([^>]+)>");
91    }
92}