diskit/lib.rs
1/*
2 diskit – Utilities for intercepting disk requests.
3 Copyright (C) 2022,2023,2026 Matthias Kaak
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Affero General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17*/
18
19#![warn(
20 clippy::all,
21 clippy::pedantic,
22 clippy::nursery,
23 rustdoc::missing_crate_level_docs,
24 missing_docs,
25 clippy::cargo_common_metadata
26)]
27// Anachronism
28#![allow(clippy::non_ascii_literal)]
29// More or less manual checked and documentation agrees with me that
30// it's usually not needed.
31#![allow(
32 clippy::cast_possible_truncation,
33 clippy::cast_sign_loss,
34 clippy::cast_precision_loss,
35 clippy::cast_lossless,
36 clippy::cast_possible_wrap
37)]
38// Currently this only warns on function which are just replicas of
39// stdlib functions and they all link to their original functions
40// (which does have an "error" section). Since I think that's it
41// obvious that these function have the same error condition this is a
42// false positive. Due to the number of such functions I don't want
43// to add this to every one on it's own. TODO: Regularly remove this
44// temporarily to check if it still only warns on these functions.
45#![allow(clippy::missing_errors_doc)]
46// It's ridiculous that this hasn't landed yet and these error codes
47// are really practical here. Since `diskit` isn't 1.0 yet, I don't
48// need to give stability guarantees, so it's fine that I use rustc
49// nightly.
50#![feature(io_error_more)]
51// A lot of structs and similar are completely pub so that others can
52// also implement diskits and if then not all fields are documented
53// this lint warns. But this is often (somewhat) wrong, since they're
54// already documented at the struct (or similar) level or at a linked
55// place. Because of this I believe that these are false positives,
56// even though I try to fix all of them over time.
57// #[allow(missing_docs)]
58// This nursery lint has a lot of false positives.
59// TODO: Remove once lint is out of nursery.
60#![allow(clippy::significant_drop_tightening)]
61
62//! Utilities for intercepting disk requests
63//!
64//! Diskit (short for "**Dis**c root **kit**") attempts to be an
65//! intransparent, rust-style root kit for intercepting and modifying
66//! requests to the hard drive. To use it, decide what you want to do
67//! with the intercepted requests and choose the appropriate diskit
68//! (e.g.: no interception -> [`StdDiskit`]; redirect to virtual file
69//! system -> [`VirtualDiskit`]; logging all requests ->
70//! [`LogDiskit`]), then route all requests through it:
71//! ```
72//! use std::io::{Read, Write};
73//! use diskit::{diskit_extend::DiskitExt, Diskit, VirtualDiskit};
74//!
75//! # fn main() -> Result<(), std::io::Error>
76//! # {
77//! // All requests are redircted to a virtual file system.
78//! let diskit = VirtualDiskit::default();
79//!
80//! // This writes "Hello, World!" in the newly created file "test.txt".
81//! let mut file1 = diskit.create("test.txt")?;
82//! file1.write_all(b"Hello, World!")?;
83//!
84//! // You can close `file1` and it still works:
85//! // file1.close()?;
86//!
87//! // This reads the just created file.
88//! let mut file2 = diskit.open("test.txt")?;
89//! let mut buf = String::new();
90//! file2.read_to_string(&mut buf)?;
91//!
92//! assert_eq!(buf, "Hello, World!");
93//!
94//! # Ok(())
95//! # }
96//! ```
97//! If you want to see how diskit would be used in a full program, see
98//! [legacylisten](https://codeberg.org/zvavybir/legacylisten), the
99//! program I wrote diskit for.
100//! # Making your own diskit
101//! You can make your own diskit by implementing the [`Diskit`] trait.
102//!
103//! Because a lot of [stdlib](std) types are intransparent, there are
104//! transparent replicas of them here that you're going to have to
105//! use. Most of these types have an inner type
106//! (e.g. [`File`](file::File) has [`FileInner`](file::FileInner)) to
107//! make the [`Diskit`] trait object-safe and this library easy to
108//! use.
109//!
110//! To make [`StdDiskit`] as overheadless as possible most types have an
111//! `Option<StdsVersionOfThisType>`, which should be [`None`] in your
112//! implementation.
113//!
114//! If your diskit internally still needs to access the disk, please
115//! consider delegating these to an other diskit like [`LogDiskit`]
116//! does.
117//! # Size of a diskit
118//! Diskits *should* (there is no way or reason to enforce it) be as
119//! small and cheaply [clone](Clone)able as possible. This is because
120//! this library should be optimized for [`StdDiskit`] (as this is
121//! expected to be it's most used – albeit most useless – diskit) and
122//! while adding diskit support to
123//! [legacylisten](https://crates.io/crates/legacylisten) it became
124//! apparent that for good usability and performance diskits are
125//! [clone](Clone)d often and passed by value.
126//!
127//! If your diskit is bigger than one [`usize`] consider wrapping it
128//! in an [`Arc`](std::sync::Arc).
129//! # Stability
130//! Diskit is still in a very early version and nothing is stable,
131//! although I *try* to keep it stable.
132//! # Contributing
133//! I have written that library specifically for
134//! [legacylisten](https://crates.io/crates/legacylisten) and added
135//! (mostly) only what I needed for that, so it's still lacking in a
136//! lot for normal usage. If you need an additional feature (or
137//! features) or otherwise have an idea how to make it better, please
138//! don't hesitate to
139//! [share](https://codeberg.org/zvavybir/diskit/issues/new) it or
140//! [implement](https://codeberg.org/zvavybir/diskit/pulls) it
141//! yourself.
142
143pub mod dir_entry;
144pub mod diskit;
145pub mod diskit_extend;
146pub mod file;
147pub mod log_diskit;
148pub mod metadata;
149pub mod open_options;
150pub mod std_diskit;
151pub mod virtual_diskit;
152pub mod void_diskit;
153pub mod walkdir;
154
155pub use crate::diskit::Diskit;
156pub use log_diskit::LogDiskit;
157pub use std_diskit::StdDiskit;
158pub use virtual_diskit::VirtualDiskit;
159pub use void_diskit::VoidDiskit;