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/// 文件处理器
8///
9/// 用于批量处理日志文件,支持单文件和多文件处理
10pub struct FileProcessor {
11    /// 输出格式化器
12    /// 负责将解析结果转换为指定格式(如JSON)
13    formatter: Box<dyn LogFormatter>,
14}
15
16impl FileProcessor {
17    /// 创建新的文件处理器
18    pub fn new() -> Self {
19        Self {
20            formatter: Box::new(JsonFormatter::new()),
21        }
22    }
23
24    /// 处理单个日志文件
25    pub fn process_file(&self, file_path: &str) -> Result<String, Box<dyn Error>> {
26        let file = fs::File::open(file_path)?;
27        let reader = BufReader::new(file);
28
29        let mut results = Vec::new();
30        let mut line_number = 0;
31
32        for line in reader.lines() {
33            let line = line?;
34            line_number += 1;
35
36            // 跳过空行
37            if line.trim().is_empty() {
38                continue;
39            }
40
41            // 解析单行日志
42            let parse_result = parse_log_line(&line);
43            results.push((line_number, line, parse_result));
44        }
45
46        // 使用格式化器输出结果
47        self.formatter.format_multiple(results)
48    }
49
50    /// 处理多个文件(未来功能)
51    pub fn process_files(&self, file_paths: &[String]) -> Result<String, Box<dyn Error>> {
52        let mut all_results = Vec::new();
53
54        for file_path in file_paths {
55            let file = fs::File::open(file_path)?;
56            let reader = BufReader::new(file);
57            let mut line_number = 0;
58
59            for line in reader.lines() {
60                let line = line?;
61                line_number += 1;
62
63                if line.trim().is_empty() {
64                    continue;
65                }
66
67                let parse_result = parse_log_line(&line);
68                all_results.push((line_number, line, parse_result));
69            }
70        }
71
72        self.formatter.format_multiple(all_results)
73    }
74
75    /// 处理单行日志(用于交互式使用)
76    pub fn process_line(&self, line: &str, line_number: usize) -> Result<String, Box<dyn Error>> {
77        let parse_result = parse_log_line(line);
78        self.formatter
79            .format_single(line_number, line, &parse_result)
80    }
81}
82
83impl Default for FileProcessor {
84    fn default() -> Self {
85        Self::new()
86    }
87}