diskit 0.1.1

Utilities for intercepting disk requests.
Documentation
/*
    diskit – Utilities for intercepting disk requests.
    Copyright (C) 2022  Matthias Kaak

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#![warn(
    clippy::all,
    clippy::pedantic,
    clippy::nursery,
    rustdoc::missing_crate_level_docs,
    missing_docs,
    //clippy::cargo_common_metadata
)]
// Anachronism
#![allow(clippy::non_ascii_literal)]
// More or less manual checked and documentation agrees with me that
// it's usually not needed.
#![allow(
    clippy::cast_possible_truncation,
    clippy::cast_sign_loss,
    clippy::cast_precision_loss,
    clippy::cast_lossless,
    clippy::cast_possible_wrap
)]
// Currently this only warns on function which are just replicas of
// stdlib functions and they all link to their original functions
// (which does have an "error" section).  Since I think that's it
// obvious that these function have the same error condition this is a
// false positive.  Due to the number of such functions I don't want
// to add this to every one on it's own.  TODO: Regularly remove this
// temporarily to check if it still only warns on these functions.
#![allow(clippy::missing_errors_doc)]
// It's ridiculous that this hasn't landed yet and these error codes
// are really practical here.  Since `diskit` isn't 1.0 yet, I don't
// need to give stability guarantees, so it's fine that I use rustc
// nightly.
#![feature(io_error_more)]
// A lot of structs and similar are completely pub so that others can
// also implement diskits and if then not all fields are documented
// this lint warns.  But this is often (somewhat) wrong, since they're
// already documented at the struct (or similar) level or at a linked
// place.  Because of this I believe that these are false positives,
// even though I try to fix all of them over time.
// #[allow(missing_docs)]

//! Utilities for intercepting disk requests
//!
//! Diskit (short for "**Dis**c root **kit**") attempts to be an
//! intransparent, rust-style root kit for intercepting and modifying
//! requests to the hard drive.  To use it, decide what you want to do
//! with the intercepted requests and choose the appropriate diskit
//! (e.g.: no interception -> [`StdDiskit`]; redirect to virtual file
//! system -> [`VirtualDiskit`]; logging all requests ->
//! [`LogDiskit`]), then route all requests through it:
//! ```
//! use std::io::{Read, Write};
//! use diskit::{diskit_extend::DiskitExt, Diskit, VirtualDiskit};
//!
//! # fn main() -> Result<(), std::io::Error>
//! # {
//! // All requests are redircted to a virtual file system.
//! let diskit = VirtualDiskit::default();
//!
//! // This writes "Hello, World!" in the newly created file "test.txt".
//! let mut file1 = diskit.create("test.txt")?;
//! file1.write_all(b"Hello, World!")?;
//!
//! // You can close `file1` and it still works:
//! // file1.close()?;
//!
//! // This reads the just created file.
//! let mut file2 = diskit.open("test.txt")?;
//! let mut buf = String::new();
//! file2.read_to_string(&mut buf)?;
//!
//! assert_eq!(buf, "Hello, World!");
//!
//! # Ok(())
//! # }
//! ```
//! If you want to see how diskit would be used in a full program, see
//! [legacylisten](https://codeberg.org/zvavybir/legacylisten), the
//! program I wrote diskit for.
//! # Making your own diskit
//! You can make your own diskit by implementing the [`Diskit`] trait.
//!
//! Because a lot of [stdlib](std) types are intransparent, there are
//! transparent replicas of them here that you're going to have to
//! use.  Most of these types have an inner type
//! (e.g. [`File`](file::File) has [`FileInner`](file::FileInner)) to
//! make the [`Diskit`] trait object-safe and this library easy to
//! use.
//!
//! To make [`StdDiskit`] as overheadless as possible most types have an
//! `Option<StdsVersionOfThisType>`, which should be [`None`] in your
//! implementation.
//!
//! If your diskit internally still needs to access the disk, please
//! consider delegating these to an other diskit like [`LogDiskit`]
//! does.
//! # Size of a diskit
//! Diskits *should* (there is no way or reason to enforce it) be as
//! small and cheaply [clone](Clone)able as possible.  This is because
//! this library should be optimized for [`StdDiskit`] (as this is
//! expected to be it's most used – albeit most useless – diskit) and
//! while adding diskit support to
//! [legacylisten](https://crates.io/crates/legacylisten) it became
//! apparent that for good usability and performance diskits are
//! [clone](Clone)d often and passed by value.
//!
//! If your diskit is bigger than one [`usize`] consider wrapping it
//! in an [`Arc`](std::sync::Arc).
//! # Stability
//! Diskit is still in a very early version and nothing is stable,
//! although I *try* to keep it stable.
//! # Contributing
//! I have written that library specifically for
//! [legacylisten](https://crates.io/crates/legacylisten) and added
//! (mostly) only what I needed for that, so it's still lacking in a
//! lot for normal usage.  If you need an additional feature (or
//! features) or otherwise have an idea how to make it better, please
//! don't hesitate to
//! [share](https://codeberg.org/zvavybir/diskit/issues/new) it or
//! [implement](https://codeberg.org/zvavybir/diskit/pulls) it
//! yourself.

pub mod dir_entry;
pub mod diskit;
pub mod diskit_extend;
pub mod file;
pub mod log_diskit;
pub mod metadata;
pub mod open_options;
pub mod std_diskit;
pub mod virtual_diskit;
pub mod void_diskit;
pub mod walkdir;

pub use crate::diskit::Diskit;
pub use log_diskit::LogDiskit;
pub use std_diskit::StdDiskit;
pub use virtual_diskit::VirtualDiskit;
pub use void_diskit::VoidDiskit;