dm_database_parser_sqllog/parser/
builder.rs1use std::fs;
2use std::path::{Path, PathBuf};
3use std::str;
4
5use crate::error::ParseError;
6use crate::parser::LogParser;
7use crate::parser::encoding::FileEncodingHint;
8
9pub struct LogParserBuilder {
11 path: PathBuf,
12 encoding_hint: Option<FileEncodingHint>,
13}
14
15impl LogParserBuilder {
16 pub fn new<P: AsRef<Path>>(path: P) -> Self {
18 Self {
19 path: path.as_ref().to_path_buf(),
20 encoding_hint: None,
21 }
22 }
23
24 pub fn encoding_hint(mut self, hint: FileEncodingHint) -> Self {
26 self.encoding_hint = Some(hint);
27 self
28 }
29
30 pub fn build(self) -> Result<LogParser, ParseError> {
32 let data = fs::read(&self.path).map_err(|e| ParseError::IoError(e.to_string()))?;
33
34 let encoding = match self.encoding_hint {
35 Some(hint) => hint,
36 None => {
37 let head_size = data.len().min(64 * 1024);
39 let head_ok = str::from_utf8(&data[..head_size]).is_ok();
40 let tail_start = data.len().saturating_sub(4 * 1024).max(head_size);
41 let tail_ok =
42 tail_start >= data.len() || str::from_utf8(&data[tail_start..]).is_ok();
43 if head_ok && tail_ok {
44 FileEncodingHint::Utf8
45 } else {
46 FileEncodingHint::Gb18030
47 }
48 }
49 };
50
51 Ok(LogParser { data, encoding })
52 }
53}