kxio 3.0.0

Provides injectable Filesystem and Network resources to make code more testable
Documentation
//! Provides an injectable reference to part of the filesystem.
//!
//! Create a new [FileSystem] to access a directory using [crate::fs::new].
//! Create a new [TempFileSystem] to access a temporary directory using [crate::fs::temp()].
//!
//! [TempFileSystem] derefs automatically to [FileSystem] so can be used anywhere
//! you would use [FileSystem].
//!
//! ```
//! # use std::path::PathBuf;
//! # use kxio::fs::FileSystem;
//! # use kxio::fs::PathReal;
//! # use kxio::fs::DirHandle;
//! # use kxio::fs::FileHandle;
//! # fn try_main() -> kxio::fs::Result<()> {
//! let fs = kxio::fs::temp()?;
//! let fs: FileSystem = kxio::fs::new(fs.base().to_path_buf());
//! let dir_path: PathBuf = fs.base().join("foo");
//! let dir: DirHandle = fs.dir(&dir_path);
//! dir.create()?;
//! let file_path = dir_path.join("bar.txt");
//! let file: FileHandle = fs.file(&file_path);
//! file.write("new file contents")?;
//! let reader = file.reader()?;
//! assert_eq!(reader.to_string(), "new file contents");
//! # Ok(())
//! # }
//! ```
//!
//! # Standard library equivalents
//!
//! Given a [FileSystem] `fs`:
//!
//! ```no_run
//! let fs = kxio::fs::temp().expect("temp fs"); // for testing
//! // or
//! # let pathbuf = fs.base().join("foo");
//! let fs = kxio::fs::new(pathbuf);
//! ```
//!
//! - [x] `std::fs::canonicalize` - `fs.path(path).canonicalize()` - Returns the canonical, absolute form of a path with all intermediate components normalized and symbolic links resolved.
//! - [x] `std::fs::copy` - `fs.file(path).copy(target)` - Copies the contents of one file to another. This function will also copy the permission bits of the original file to the destination file.
//! - [x] `std::fs::create_dir` - `fs.dir(path).create()` - Creates a new, empty directory at the provided path
//! - [x] `std::fs::create_dir_all` - `fs.dir(path).create_all()` - Recursively create a directory and all of its parent components if they are missing.
//! - [x] `std::fs::hard_link` - `fs.file(path).hard_link(other)` - Creates a new hard link on the filesystem.
//! - [x] `std::fs::metadata` - `fs.path(path).metadata()` - Given a path, query the file system to get information about a file, directory, etc.
//! - [x] `std::fs::read` - `fs.file(path).reader().bytes()` - Read the entire contents of a file into a bytes vector.
//! - [x] `std::fs::read_dir` - `fs.dir(path).read()` - Returns an iterator over the entries within a directory.
//! - [x] `std::fs::read_link` - `fs.path(path).read_link()` - Reads a symbolic link, returning the file that the link points to.
//! - [x] `std::fs::read_to_string` - `fs.file(path).reader().to_string()` - Read the entire contents of a file into a string.
//! - [x] `std::fs::remove_dir` - `fs.dir(path).remove()` - Removes an empty directory.
//! - [x] `std::fs::remove_dir_all` - `fs.dir(path).remove_all()` - Removes a directory at this path, after removing all its contents. Use carefully!
//! - [x] `std::fs::remove_file` - `fs.file(path).remove()` - Removes a file from the filesystem.
//! - [x] `std::fs::rename` - `fs.path(path).rename()` - Rename a file or directory to a new name, replacing the original file if to already exists.
//! - [x] `std::fs::set_permissions` - `fs.path(path).set_permissions(perms)` - Changes the permissions found on a file or a directory.
//! - [x] `std::fs::symlink_metadata` - `fs.path(path).symlink_metadata()` - Query the metadata about a file without following symlinks.
//! - [x] `std::fs::write` - `fs.file(path).write()` - Write a slice as the entire contents of a file.
//!
use std::path::PathBuf;

mod dir;
mod dir_item;
mod file;
mod path;
mod reader;
mod result;
mod system;
mod temp;

pub use dir_item::{DirItem, DirItemIterator};
pub use path::{DirMarker, FileMarker, PathMarker, PathReal};
pub use reader::Reader;
pub use result::{Error, Result};
pub use system::{DirHandle, FileHandle, FileSystem, PathHandle};
pub use temp::TempFileSystem;

/// Creates a new `FileSystem` for the path.
///
/// This will create a `FileSystem` that provides access to the
/// filesystem under the given path.
///
/// Any attempt to access outside this base will result in a
/// `error::Error::PathTraversal` error when attempting the
/// opertation.
pub fn new(base: impl Into<PathBuf>) -> FileSystem {
    FileSystem::new(base.into())
}

/// Creates a new `TempFileSystem` for a temporary directory.
///
/// The `TempFileSystem` provides a `Deref` to a `FileSystem` for
/// the temporary directory.
///
/// When the `TempFileSystem` is dropped, the temporary directory
/// is deleted.
///
/// Returns an error if the temporary directory cannot be created.
pub fn temp() -> Result<temp::TempFileSystem> {
    temp::TempFileSystem::new()
}

#[cfg(test)]
mod tests {
    use super::*;

    fn is_normal<T: Sized + Send + Sync + Unpin>() {}

    #[test]
    fn normal_types() {
        is_normal::<FileSystem>();
        is_normal::<DirItem>();
        is_normal::<DirItemIterator>();
        is_normal::<Reader>();
        is_normal::<PathReal<PathMarker>>();
        is_normal::<DirMarker>();
        is_normal::<FileMarker>();
        is_normal::<PathMarker>();
        is_normal::<DirHandle>();
        is_normal::<FileHandle>();
        is_normal::<PathHandle<PathMarker>>();
    }
}