postfix_log_parser/
file_processor.rs

1use crate::formatters::{json::JsonFormatter, LogFormatter};
2use crate::parse_log_line;
3use std::error::Error;
4use std::fs;
5use std::io::{BufRead, BufReader};
6
7/// 文件处理器
8pub struct FileProcessor {
9    formatter: Box<dyn LogFormatter>,
10}
11
12impl FileProcessor {
13    /// 创建新的文件处理器
14    pub fn new() -> Self {
15        Self {
16            formatter: Box::new(JsonFormatter::new()),
17        }
18    }
19
20    /// 处理单个日志文件
21    pub fn process_file(&self, file_path: &str) -> Result<String, Box<dyn Error>> {
22        let file = fs::File::open(file_path)?;
23        let reader = BufReader::new(file);
24
25        let mut results = Vec::new();
26        let mut line_number = 0;
27
28        for line in reader.lines() {
29            let line = line?;
30            line_number += 1;
31
32            // 跳过空行
33            if line.trim().is_empty() {
34                continue;
35            }
36
37            // 解析单行日志
38            let parse_result = parse_log_line(&line);
39            results.push((line_number, line, parse_result));
40        }
41
42        // 使用格式化器输出结果
43        self.formatter.format_multiple(results)
44    }
45
46    /// 处理多个文件(未来功能)
47    pub fn process_files(&self, file_paths: &[String]) -> Result<String, Box<dyn Error>> {
48        let mut all_results = Vec::new();
49
50        for file_path in file_paths {
51            let file = fs::File::open(file_path)?;
52            let reader = BufReader::new(file);
53            let mut line_number = 0;
54
55            for line in reader.lines() {
56                let line = line?;
57                line_number += 1;
58
59                if line.trim().is_empty() {
60                    continue;
61                }
62
63                let parse_result = parse_log_line(&line);
64                all_results.push((line_number, line, parse_result));
65            }
66        }
67
68        self.formatter.format_multiple(all_results)
69    }
70
71    /// 处理单行日志(用于交互式使用)
72    pub fn process_line(&self, line: &str, line_number: usize) -> Result<String, Box<dyn Error>> {
73        let parse_result = parse_log_line(line);
74        self.formatter
75            .format_single(line_number, line, &parse_result)
76    }
77}