1pub type Result<T> = crate::VfResult<T>;
11pub type Error = crate::VfError;
12pub use crate::{
13 AttrMask as Attributes, Attrs, Capabilities, CopyOption, DirEntry, ErrorDomain,
14 FilesystemStats, OpenFlags, OpenOp, Permissions, RemoveOptions, StatusCode, TransportKind,
15 VfType as FileType,
16};
17#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
19pub enum RenameOptions {
20 #[default]
22 Replace,
23 NoReplace,
25 Exchange,
29}
30pub use std::io::ErrorKind;
31pub use std::ops::ControlFlow;
32mod io;
33pub use io::SyncMode;
34mod builders;
35pub use builders::OpenOptions;
36mod traits;
37pub use traits::{DirHandle, FileHandle, Vfsi, VfsiExt};
38mod metadata;
39pub use metadata::{AttrsOptions, SetAttrsOp};
40mod mkdir;
41pub use mkdir::MkDirOp;
42mod read;
43pub use read::{ReadOp, ReadOptions, ReadResult};
44mod write;
45pub use write::{WriteOp, WriteOptions};
46mod visit;
47pub use visit::ListDirOptions;
48mod support;
49pub use support::{
50 DEFAULT_DIRECTORY_MAX_ENTRIES, DEFAULT_DIRECTORY_MAX_PATH_BYTES,
51 DEFAULT_READ_ALLV_MAX_TOTAL_BYTES, DEFAULT_READ_MAX_BYTES, DEFAULT_READ_STREAM_CHUNK_BYTES,
52 DEFAULT_READV_MAX_TOTAL_BYTES, DEFAULT_WALK_MAX_DEPTH, DepthLimit, DirectoryListing,
53 ResourceLimits, StreamCompletion, StreamOptions, TraversalCompletion,
54};
55pub use support::{ReadIntoResult, WriteResult};
56mod listdir;
57mod traversal;
58#[doc(hidden)]
59pub use traversal::walk_events;
60pub use traversal::{WalkControl, WalkEvent, WalkEventKind};
61#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
63pub enum RemoveMode {
64 #[default]
66 Entry,
67 Tree,
69 Contents,
72}
73
74#[doc(hidden)]
76pub mod internal {
77 pub use super::read::{ReadRequest, consume_ops, read_batch};
78 pub use super::support::FsReadResult as OwnedReadResult;
79}
80
81pub mod prelude {
83 pub use super::{
84 AsTarget, Attributes, AttrsOptions, ControlFlow, CopyOption, DirHandle, FileHandle,
85 ListDirOptions, MkDirOp, OpenFlags, OpenOp, ReadOp, ReadOptions, ReadResult, RemoveMode,
86 RemoveOptions, RenameOptions, ResourceLimits, SetAttrsOp, StreamOptions, SyncMode, Target,
87 Vfsi, VfsiExt, WriteOp, WriteOptions,
88 };
89}
90
91#[derive(Debug)]
96pub enum Target<'a, F> {
97 Path(&'a std::path::Path),
98 File(&'a F),
99}
100impl<F> Copy for Target<'_, F> {}
101impl<F> Clone for Target<'_, F> {
102 fn clone(&self) -> Self {
103 *self
104 }
105}
106impl<F> Target<'_, F> {
107 pub fn path(path: &impl AsRef<std::path::Path>) -> Target<'_, F> {
108 Target::Path(path.as_ref())
109 }
110 pub fn file(file: &F) -> Target<'_, F> {
111 Target::File(file)
112 }
113}
114pub trait AsTarget<F> {
119 fn as_target(&self) -> Target<'_, F>;
120}
121impl<F, P: AsRef<std::path::Path>> AsTarget<F> for P {
122 fn as_target(&self) -> Target<'_, F> {
123 Target::Path(self.as_ref())
124 }
125}
126impl<F> AsTarget<F> for Target<'_, F> {
127 fn as_target(&self) -> Target<'_, F> {
128 match self {
129 Self::Path(path) => Target::Path(path),
130 Self::File(file) => Target::File(file),
131 }
132 }
133}
134
135#[cfg(test)]
136mod target_tests {
137 use super::*;
138 #[test]
139 fn borrowed_targets_and_handle_operations_do_not_require_cloning_handles() {
140 struct NonClone;
141 fn copy<T: Copy>(value: T) -> (T, T) {
142 (value, value)
143 }
144 let file = NonClone;
145 let (first, second) = copy(Target::file(&file));
146 for target in [first, second.as_target()] {
147 assert!(matches!(target, Target::File(actual) if std::ptr::eq(actual, &file)));
148 }
149 let (first, second) = copy(SetAttrsOp::file(&file).len(0).follow_symlinks(false));
150 for op in [first, second] {
151 assert_eq!(op.requested_len(), Some(0));
152 assert!(!op.follows_symlinks());
153 assert!(matches!(op.target(), Target::File(actual) if std::ptr::eq(*actual, &file)));
154 }
155 let path = std::path::Path::new("/file");
156 let direct: Target<'_, NonClone> = path.as_target();
157 let explicit: Target<'_, NonClone> = Target::path(&path);
158 for target in [direct, explicit] {
159 assert!(matches!(target, Target::Path(actual) if actual == path));
160 }
161 }
162}