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/// let pattern = create_queue_id_pattern(r"^{QUEUE_ID}: to=<([^>]+)>");
39/// // 结果: r"^([0-9A-Za-z]{10,20}): to=<([^>]+)>"
40/// ```
41pub fn create_queue_id_pattern(pattern: &str) -> String {
42    pattern.replace("{QUEUE_ID}", *QUEUE_ID_PATTERN)
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_extract_queue_id_new_format() {
51        let message = "4bG4VR5zTgz6pqsd: client=localhost[127.0.0.1]:60166";
52        let result = extract_queue_id(message);
53        assert_eq!(result, Some("4bG4VR5zTgz6pqsd".to_string()));
54    }
55
56    #[test]
57    fn test_extract_queue_id_various_formats() {
58        let test_cases = vec![
59            (
60                "4bG5rK2jJfz6pr1t: message-id=<test@example.com>",
61                Some("4bG5rK2jJfz6pr1t".to_string()),
62            ),
63            (
64                "4bG6s970Nhz6qsfY: to=<user@example.com>",
65                Some("4bG6s970Nhz6qsfY".to_string()),
66            ),
67            (
68                "4bG6sC3LJbz6qsfc: from=<sender@example.com>",
69                Some("4bG6sC3LJbz6qsfc".to_string()),
70            ),
71            ("no queue id in this message", None),
72            ("ABC123: too short", None),
73            ("4bG5rK2jJfz6pr1tTooLong: too long", None),
74        ];
75
76        for (input, expected) in test_cases {
77            assert_eq!(
78                extract_queue_id(input),
79                expected,
80                "Failed for input: {}",
81                input
82            );
83        }
84    }
85
86    #[test]
87    fn test_create_queue_id_pattern() {
88        let pattern = create_queue_id_pattern(r"^{QUEUE_ID}: to=<([^>]+)>");
89        assert_eq!(pattern, r"^([0-9A-Za-z]{10,20}): to=<([^>]+)>");
90    }
91}