/*
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/>.
*/
// Anachronism
// More or less manual checked and documentation agrees with me that
// it's usually not needed.
// 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.
// 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.
// 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 use crate Diskit;
pub use LogDiskit;
pub use StdDiskit;
pub use VirtualDiskit;
pub use VoidDiskit;