use std::path::PathBuf;
use std::{ffi::OsString, path::Path};
use eyre::ContextCompat;
use crate::filesystem::{DirListing, FileSystem};
use crate::models::{FileInfo, SimpleFileKind};
pub struct MockFs {
root: MockFsNode,
}
impl MockFs {
pub fn new(root: MockFsNode) -> Self {
Self { root }
}
}
pub struct MockFsNode {
name: OsString,
kind: SimpleFileKind,
children: Vec<MockFsNode>,
}
impl MockFsNode {
fn to_file_info(&self, parent: &Path) -> FileInfo {
let mut new_path = parent.to_path_buf();
new_path.push(&self.name);
FileInfo::new(new_path, self.name.to_string_lossy().to_string(), self.kind)
}
pub fn file(name: &str) -> Self {
MockFsNode {
name: name.into(),
kind: SimpleFileKind::File,
children: Vec::new(),
}
}
pub fn dir(name: &str, children: Vec<MockFsNode>) -> Self {
MockFsNode {
name: name.into(),
kind: SimpleFileKind::Directory,
children,
}
}
pub fn empty_dir(name: &str) -> Self {
Self::dir(name, Vec::new())
}
}
impl MockFs {
fn node(&self, path: &Path) -> Option<&MockFsNode> {
let mut current = &self.root;
for c in path.iter().skip(1) {
current = current.children.iter().find(|n| n.name == c)?;
}
Some(current)
}
}
impl FileSystem for MockFs {
fn directory_from_current<P: AsRef<Path>>(&self, path: Option<P>) -> eyre::Result<FileInfo> {
let mut path_buf: PathBuf = "/home/user".into();
if let Some(p) = path {
path_buf.push(p);
}
Ok(FileInfo::new(
path_buf,
"user".to_string(),
SimpleFileKind::Directory,
))
}
fn list_files(&self, file: &FileInfo) -> eyre::Result<DirListing> {
let path = &file.path;
let node = self.node(path).wrap_err("Cannot find node")?;
let entries = node
.children
.iter()
.map(|node| node.to_file_info(path))
.collect();
Ok(DirListing {
entries,
errors: Vec::new(),
})
}
fn file_size(&self, _file: &FileInfo) -> eyre::Result<u64> {
Ok(42)
}
}