use crate::{Config, Error, Result};
use log::{debug, info};
use std::fs;
use std::path::{Path, PathBuf};
pub fn path_to_str<P: AsRef<Path>>(path: P) -> String {
path.as_ref().to_string_lossy().to_string()
}
pub fn read_to_string<P: AsRef<Path>>(path: P) -> Result<String> {
let path = path.as_ref();
fs::read_to_string(path).map_err(|e| Error::Io(path.to_path_buf(), e))
}
pub fn read_to_string_opt<P: AsRef<Path>>(path: P) -> Result<Option<String>> {
let path = path.as_ref();
if fs::metadata(path).is_err() {
return Ok(None);
}
read_to_string(path).map(Some)
}
pub fn ensure_dir(path: &Path) -> Result<()> {
if fs::metadata(path).is_err() {
fs::create_dir(path).map_err(|e| Error::Io(path.to_path_buf(), e))?;
info!("Created directory: {}", path_to_str(path));
}
let meta = fs::metadata(path).map_err(|e| Error::Io(path.to_path_buf(), e))?;
if !meta.is_dir() {
return Err(Error::ExpectedDir(path_to_str(path)));
}
Ok(())
}
pub fn rm_gitkeep(path: &Path) -> Result<()> {
let path = path.join(".gitkeep");
if fs::metadata(&path).is_ok() {
fs::remove_file(&path).map_err(|e| Error::Io(path.to_path_buf(), e))?;
debug!("Removed .gitkeep file from: {}", path_to_str(&path));
}
Ok(())
}
pub fn read_and_filter_dir<F>(path: &Path, filter: F) -> Result<Vec<PathBuf>>
where
F: Fn(fs::DirEntry) -> Option<Result<PathBuf>>,
{
fs::read_dir(path)
.map_err(|e| Error::Io(path.to_path_buf(), e))?
.filter_map(|r| match r {
Ok(e) => filter(e),
Err(e) => Some(Err(Error::Io(path.to_path_buf(), e))),
})
.collect::<Result<Vec<PathBuf>>>()
}
pub fn entry_filter(config: &Config, entry: fs::DirEntry) -> Option<Result<PathBuf>> {
let meta = match entry.metadata() {
Ok(m) => m,
Err(e) => return Some(Err(Error::Io(entry.path(), e))),
};
let path = entry.path();
let ext = path.extension()?.to_str()?;
if meta.is_file() && ext == config.change_sets.entry_ext {
Some(Ok(path))
} else {
None
}
}
pub fn get_relative_path<P: AsRef<Path>, Q: AsRef<Path>>(path: P, prefix: Q) -> Result<PathBuf> {
Ok(path.as_ref().strip_prefix(prefix.as_ref())?.to_path_buf())
}
pub fn file_exists<P: AsRef<Path>>(path: P) -> bool {
let path = path.as_ref();
if let Ok(meta) = fs::metadata(path) {
return meta.is_file();
}
false
}
pub fn dir_exists<P: AsRef<Path>>(path: P) -> bool {
let path = path.as_ref();
if let Ok(meta) = fs::metadata(path) {
return meta.is_dir();
}
false
}
#[cfg(test)]
mod test {
use super::get_relative_path;
#[test]
fn relative_path_extraction() {
assert_eq!(
"mypackage",
get_relative_path("/path/to/mypackage", "/path/to")
.unwrap()
.to_str()
.unwrap()
)
}
}