#[cfg(test)]
#[path = "file_tests.rs"]
mod file_tests;
use crate::traits::{LoaderInfo, LoaderType, LogLoader, Result};
use std::path::PathBuf;
#[derive(Debug)]
pub struct FileLoader {
path: PathBuf,
info: LoaderInfo,
}
impl FileLoader {
pub fn new(path: impl Into<PathBuf>, multiline: bool) -> Self {
let path = path.into();
let id = path.display().to_string();
Self {
info: LoaderInfo {
id,
loader_type: LoaderType::TextFile,
multiline_enabled: multiline,
sample_lines: Vec::new(),
},
path,
}
}
}
impl LogLoader for FileLoader {
fn info(&self) -> &LoaderInfo {
&self.info
}
fn load(&mut self) -> Result<Vec<String>> {
let is_gzip = self
.path
.extension()
.and_then(|e| e.to_str())
.map(|ext| {
let ext = ext.to_ascii_lowercase();
ext == "gz" || ext == "gzip"
})
.unwrap_or(false);
let content = if is_gzip {
use flate2::read::GzDecoder;
use std::io::Read;
let file = std::fs::File::open(&self.path)?;
let mut decoder = GzDecoder::new(file);
let mut decompressed = Vec::new();
decoder.read_to_end(&mut decompressed).map_err(|e| {
std::io::Error::new(
e.kind(),
format!(
"Failed to decompress gzip file '{}': {}",
self.path.display(),
e
),
)
})?;
String::from_utf8(decompressed).map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Decompressed gzip file '{}' contains invalid UTF-8: {}",
self.path.display(),
e
),
)
})?
} else {
std::fs::read_to_string(&self.path)?
};
let lines: Vec<String> = content.lines().map(|l| l.to_string()).collect();
self.info.sample_lines = lines.iter().take(10).cloned().collect();
Ok(lines)
}
}