use crate::entry::Entry;
use crate::error::Error;
use crate::walk::StorageHint;
use std::os::unix::fs::MetadataExt;
use std::path::Path;
pub(super) fn build_relative_path(prefix: &str, name: &str) -> String {
if prefix.is_empty() {
name.to_owned()
} else {
let mut s = String::with_capacity(prefix.len() + 1 + name.len());
s.push_str(prefix);
s.push(std::path::MAIN_SEPARATOR);
s.push_str(name);
s
}
}
pub fn scan_dir_platform(
path: &Path,
prefix: &str,
_hint: StorageHint,
) -> Result<Vec<Entry>, Error> {
let mut entries = Vec::with_capacity(32);
let mut child_path = path.to_path_buf();
for result in std::fs::read_dir(path).map_err(|e| Error::Io {
path: path.to_path_buf(),
source: e,
})? {
let dir_entry = match result {
Ok(e) => e,
Err(_) => continue,
};
let raw_name = dir_entry.file_name();
let name_str = raw_name.to_string_lossy();
child_path.push(name_str.as_ref());
let meta = match std::fs::symlink_metadata(&child_path) {
Ok(m) => m,
Err(_) => {
child_path.pop();
continue;
}
};
child_path.pop();
let is_symlink = meta.file_type().is_symlink();
let is_dir = meta.is_dir();
let is_hidden = name_str.starts_with('.');
let relative_path = build_relative_path(prefix, &name_str);
let modified = meta.mtime();
let size = if is_symlink { 0 } else { meta.len() };
entries.push(Entry {
relative_path,
depth: 0,
size,
is_dir,
is_symlink,
is_hidden,
modified,
});
}
Ok(entries)
}