garbage-fs 0.1.0

Abstraction layer for filesystems
Documentation
pub mod stdfs;

#[cfg(test)]
pub mod mock;

use std::fs::Metadata;
use std::io::{ErrorKind, Result as IoResult, Write};
use std::path::{Path, PathBuf};

/// Abstraction for all filesystem operations
pub trait Filesystem {
  type File: File;

  fn create_dir<P: AsRef<Path>>(&self, path: P) -> IoResult<()>;

  fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> IoResult<()>;

  fn rename<P: AsRef<Path>, Q: AsRef<Path>>(
    &self,
    from: P,
    to: Q,
  ) -> IoResult<()>;

  fn remove_file<P: AsRef<Path>>(&self, path: P) -> IoResult<()>;

  fn remove_dir_all<P: AsRef<Path>>(&self, path: P) -> IoResult<()>;

  fn read_link<P: AsRef<Path>>(&self, path: P) -> IoResult<PathBuf>;

  fn path_metadata<P: AsRef<Path>>(&self, path: P) -> IoResult<Metadata>;

  fn symlink_metadata<P: AsRef<Path>>(&self, path: P) -> IoResult<Metadata>;

  fn file_metadata(&self, file: &Self::File) -> IoResult<Metadata>;

  fn path_exists<P: AsRef<Path>>(&self, path: P) -> IoResult<bool>;

  /// Check if a path exists WITHOUT resolving symlinks.
  fn symlink_exists<P: AsRef<Path>>(&self, path: P) -> IoResult<bool> {
    match self.symlink_metadata(path) {
      Ok(_) => Ok(true),
      Err(err) if matches!(err.kind(), ErrorKind::NotFound) => Ok(false),
      Err(err) => Err(err.into()),
    }
  }

  // File stuff

  /// File::open
  fn open_file<P: AsRef<Path>>(&self, path: P) -> IoResult<Self::File>;

  /// File::create
  fn create_file<P: AsRef<Path>>(&self, path: P) -> IoResult<Self::File>;
}

/// Abstraction for all file operations
pub trait File: Write {}