mod async_fs;
mod memory;
#[cfg(not(target_arch = "wasm32"))]
mod native;
mod callback_registry;
mod event_fs;
mod events;
#[cfg(feature = "crdt")]
mod crdt_fs;
#[cfg(feature = "crdt")]
mod decorator_stack;
pub use async_fs::{AsyncFileSystem, BoxFuture, SyncToAsyncFs};
#[cfg(test)]
pub(crate) use async_fs::block_on_test;
pub use memory::InMemoryFileSystem;
#[cfg(not(target_arch = "wasm32"))]
pub use native::RealFileSystem;
pub use callback_registry::{CallbackRegistry, EventCallback, SubscriptionId};
pub use event_fs::EventEmittingFs;
pub use events::FileSystemEvent;
#[cfg(feature = "crdt")]
pub use crdt_fs::CrdtFs;
#[cfg(feature = "crdt")]
pub use decorator_stack::{DecoratedFs, DecoratedFsBuilder};
use std::io::{Error, ErrorKind, Result};
use std::path::{Path, PathBuf};
pub trait FileSystem: Send + Sync {
fn read_to_string(&self, path: &Path) -> Result<String>;
fn write_file(&self, path: &Path, content: &str) -> Result<()>;
fn create_new(&self, path: &Path, content: &str) -> Result<()>;
fn delete_file(&self, path: &Path) -> Result<()>;
fn list_md_files(&self, dir: &Path) -> Result<Vec<PathBuf>>;
fn exists(&self, path: &Path) -> bool;
fn create_dir_all(&self, path: &Path) -> Result<()>;
fn is_dir(&self, path: &Path) -> bool;
fn is_symlink(&self, _path: &Path) -> bool {
false
}
fn move_file(&self, from: &Path, to: &Path) -> Result<()>;
fn read_binary(&self, path: &Path) -> Result<Vec<u8>> {
self.read_to_string(path).map(|s| s.into_bytes())
}
fn write_binary(&self, _path: &Path, _content: &[u8]) -> Result<()> {
Err(Error::new(
ErrorKind::Unsupported,
"Binary write not supported",
))
}
fn list_files(&self, _dir: &Path) -> Result<Vec<PathBuf>> {
Ok(vec![])
}
fn list_md_files_recursive(&self, dir: &Path) -> Result<Vec<PathBuf>> {
let mut all_files = self.list_md_files(dir)?;
if let Ok(entries) = self.list_files(dir) {
for entry in entries {
if self.is_dir(&entry)
&& let Ok(subdir_files) = self.list_md_files_recursive(&entry)
{
all_files.extend(subdir_files);
}
}
}
Ok(all_files)
}
fn list_all_files_recursive(&self, dir: &Path) -> Result<Vec<PathBuf>> {
let mut all_entries = Vec::new();
if let Ok(entries) = self.list_files(dir) {
for entry in entries {
all_entries.push(entry.clone());
if self.is_dir(&entry)
&& let Ok(subdir_entries) = self.list_all_files_recursive(&entry)
{
all_entries.extend(subdir_entries);
}
}
}
Ok(all_entries)
}
fn get_modified_time(&self, _path: &Path) -> Option<i64> {
None
}
}
impl<T: FileSystem> FileSystem for &T {
fn read_to_string(&self, path: &Path) -> Result<String> {
(*self).read_to_string(path)
}
fn write_file(&self, path: &Path, content: &str) -> Result<()> {
(*self).write_file(path, content)
}
fn create_new(&self, path: &Path, content: &str) -> Result<()> {
(*self).create_new(path, content)
}
fn delete_file(&self, path: &Path) -> Result<()> {
(*self).delete_file(path)
}
fn list_md_files(&self, dir: &Path) -> Result<Vec<PathBuf>> {
(*self).list_md_files(dir)
}
fn exists(&self, path: &Path) -> bool {
(*self).exists(path)
}
fn create_dir_all(&self, path: &Path) -> Result<()> {
(*self).create_dir_all(path)
}
fn is_dir(&self, path: &Path) -> bool {
(*self).is_dir(path)
}
fn is_symlink(&self, path: &Path) -> bool {
(*self).is_symlink(path)
}
fn move_file(&self, from: &Path, to: &Path) -> Result<()> {
(*self).move_file(from, to)
}
fn read_binary(&self, path: &Path) -> Result<Vec<u8>> {
(*self).read_binary(path)
}
fn write_binary(&self, path: &Path, content: &[u8]) -> Result<()> {
(*self).write_binary(path, content)
}
fn list_files(&self, dir: &Path) -> Result<Vec<PathBuf>> {
(*self).list_files(dir)
}
fn get_modified_time(&self, path: &Path) -> Option<i64> {
(*self).get_modified_time(path)
}
}