mod discover;
mod read;
use std::path::{Path, PathBuf};
pub use discover::{discover_log_files, filter_files_by_date, LogFile};
#[cfg(feature = "tui")]
pub use read::open_full_tail_reader;
pub use read::{
lazy_log_reader, lossy_line_iter, open_log_file, open_log_reader, open_tail_reader,
ReadFailures,
};
pub const DEFAULT_MAX_LINE_BYTES: usize = 1 << 20;
#[derive(Clone)]
pub struct Segment {
pub name: String,
pub path: PathBuf,
}
impl Segment {
pub fn new(path: PathBuf) -> Self {
Segment {
name: display_name(&path),
path,
}
}
}
pub fn display_name(path: &Path) -> String {
path.file_name()
.unwrap_or_default()
.to_string_lossy()
.into_owned()
}
pub fn resolve_log_path(dir: &Path, file: Option<&str>) -> PathBuf {
let Some(path) = file.map(PathBuf::from) else {
return dir.join("freeswitch.log");
};
if path.is_absolute() || path.exists() {
path
} else {
dir.join(path)
}
}
pub fn format_size(bytes: u64) -> String {
const KB: u64 = 1024;
const MB: u64 = 1024 * KB;
const GB: u64 = 1024 * MB;
if bytes >= GB {
format!("{:.1}G", bytes as f64 / GB as f64)
} else if bytes >= MB {
format!("{:.1}M", bytes as f64 / MB as f64)
} else if bytes >= KB {
format!("{:.1}K", bytes as f64 / KB as f64)
} else {
format!("{bytes}B")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn format_size_megabytes() {
assert_eq!(format_size(12_900_000), "12.3M");
}
#[test]
fn format_size_gigabytes() {
assert_eq!(format_size(2_147_483_648), "2.0G");
}
#[test]
fn format_size_kilobytes() {
assert_eq!(format_size(500_000), "488.3K");
}
#[test]
fn format_size_bytes() {
assert_eq!(format_size(512), "512B");
}
}