use anyhow;
use std::path::{Path, PathBuf};
pub trait FsBackend {
fn root(&self) -> &Path;
fn cwd(&self) -> &Path;
fn to_host<P: AsRef<Path>>(&self, inner_path: P) -> Result<PathBuf>;
fn cd<P: AsRef<Path>>(&mut self, path: P) -> Result<()>;
fn exists<P: AsRef<Path>>(&self, path: P) -> bool;
fn is_dir<P: AsRef<Path>>(&self, path: P) -> Result<bool>;
fn is_file<P: AsRef<Path>>(&self, path: P) -> Result<bool>;
fn ls<P: AsRef<Path>>(&self, path: P) -> Result<impl Iterator<Item = &Path>>;
fn tree<P: AsRef<Path>>(&self, path: P) -> Result<impl Iterator<Item = &Path>>;
fn mkdir<P: AsRef<Path>>(&mut self, path: P) -> Result<()>;
fn mkfile<P: AsRef<Path>>(&mut self, file_path: P, content: Option<&[u8]>) -> Result<()>;
fn read<P: AsRef<Path>>(&self, path: P) -> Result<Vec<u8>>;
fn write<P: AsRef<Path>>(&mut self, path: P, content: &[u8]) -> Result<()>;
fn append<P: AsRef<Path>>(&mut self, path: P, content: &[u8]) -> Result<()>;
fn rm<P: AsRef<Path>>(&mut self, path: P) -> Result<()>;
fn cleanup(&mut self) -> bool;
}
pub type Result<T> = std::result::Result<T, anyhow::Error>;
pub mod utils {
use super::Result;
use std::path::{Component, Path, PathBuf};
pub fn normalize<P: AsRef<Path>>(path: P) -> PathBuf {
let mut result = PathBuf::new();
for component in path.as_ref().components() {
match component {
Component::CurDir => {}
Component::ParentDir => {
result.pop();
}
_ => {
result.push(component);
}
}
}
if result != PathBuf::from("/") && result.ends_with("/") {
result.pop();
}
result
}
pub fn is_virtual_root<P: AsRef<Path>>(path: P) -> bool {
let components: Vec<_> = path.as_ref().components().collect();
components.len() == 1 && components[0] == Component::RootDir
}
pub fn rm_on_host<P: AsRef<Path>>(host_path: P) -> Result<()> {
let host_path = host_path.as_ref();
if host_path.is_dir() {
std::fs::remove_dir_all(host_path)?
} else {
std::fs::remove_file(host_path)?
}
Ok(())
}
}