bugreport/collector/
directory_entries.rsuse std::fs::{self, DirEntry};
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use crate::{report::ReportEntry, Collector, CrateInfo, Result};
use super::CollectionError;
pub struct DirectoryEntries {
title: String,
path: PathBuf,
}
impl<'a> DirectoryEntries {
pub fn new<P: AsRef<Path>>(title: &'a str, path: P) -> Self {
Self {
title: title.into(),
path: path.as_ref().to_path_buf(),
}
}
}
impl Collector for DirectoryEntries {
fn description(&self) -> &str {
&self.title
}
fn collect(&mut self, _: &CrateInfo) -> Result<ReportEntry> {
let path_str = &self.path.to_string_lossy();
let mut entries = fs::read_dir(&self.path)
.map_err(|e| read_dir_error_to_report_entry(e, path_str))?
.map(|e| match e {
Ok(dir_entry) => dir_entry_to_report_entry(dir_entry),
Err(e) => format!("Error: {}", e),
})
.collect::<Vec<_>>();
entries.sort();
if entries.is_empty() {
Ok(ReportEntry::Text(format!("'{}' is empty", path_str)))
} else {
Ok(ReportEntry::List(
entries.into_iter().map(ReportEntry::Text).collect(),
))
}
}
}
fn read_dir_error_to_report_entry(error: std::io::Error, path_str: &str) -> CollectionError {
CollectionError::CouldNotRetrieve(if error.kind() == ErrorKind::NotFound {
format!("'{}' not found", path_str)
} else {
format!("'{}' not read: {}", path_str, error)
})
}
fn dir_entry_to_report_entry(dir_entry: DirEntry) -> String {
let mut text = String::new();
text.push_str(&dir_entry.file_name().to_string_lossy());
if let Ok(metadata) = dir_entry.metadata() {
if metadata.is_file() {
text.push_str(&format!(", {} bytes", metadata.len()));
} else if metadata.is_dir() {
text.push(std::path::MAIN_SEPARATOR);
}
}
text
}