use std::borrow::Cow;
use std::io::ErrorKind;
use std::path::Path;
use std::{fs, io, path};
use walkdir::WalkDir;
use crate::ocfl::error::Result;
pub const BACKSLASH_SEPARATOR: bool = path::MAIN_SEPARATOR == '\\';
pub fn clean_dirs_up(start_dir: impl AsRef<Path>) -> Result<()> {
let mut current = start_dir.as_ref();
while dir_is_empty(current)? {
fs::remove_dir(current)?;
current = current.parent().unwrap();
}
Ok(())
}
pub fn clean_dirs_down(start_dir: impl AsRef<Path>) -> Result<()> {
let start_dir = start_dir.as_ref();
for entry in WalkDir::new(start_dir).contents_first(true) {
let path = entry?;
if path.file_type().is_dir() && dir_is_empty(path.path())? {
fs::remove_dir(path.path())?;
}
}
Ok(())
}
pub fn remove_file_ignore_not_found(path: impl AsRef<Path>) -> io::Result<()> {
if let Err(e) = fs::remove_file(path) {
if e.kind() != ErrorKind::NotFound {
return Err(e);
}
}
Ok(())
}
pub fn dir_is_empty(dir: impl AsRef<Path>) -> Result<bool> {
Ok(fs::read_dir(dir)?.next().is_none())
}
pub fn convert_forwardslash_to_back(path: &str) -> Cow<str> {
if BACKSLASH_SEPARATOR && path.contains('/') {
return Cow::Owned(path.replace('/', "\\"));
}
path.into()
}
pub fn convert_backslash_to_forward(path: &str) -> Cow<str> {
if BACKSLASH_SEPARATOR && path.contains('\\') {
return Cow::Owned(path.replace('\\', "/"));
}
path.into()
}
pub fn trim_trailing_slashes(path: &str) -> &str {
path.trim_end_matches('/')
}
pub fn trim_leading_slashes(path: &str) -> &str {
path.trim_start_matches('/')
}
pub fn trim_slashes(path: &str) -> &str {
trim_trailing_slashes(trim_leading_slashes(path))
}