1pub type Result<T> = crate::VfResult<T>;
18pub type Error = crate::VfError;
19pub use crate::{
20 AttrMask as Attributes, Attrs, Capabilities, CopyOptions, DirEntry, ErrorDomain,
21 FilesystemStats, FsObjId, OpenFlags, OpenOp, Permissions, RemoveOptions, StatusCode,
22 TransportKind, VfType as FileType,
23};
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
26pub enum RenameMode {
27 #[default]
29 Replace,
30 NoReplace,
32 Exchange,
36}
37pub use std::io::ErrorKind;
38pub use std::ops::ControlFlow;
39mod io;
40pub use io::SyncMode;
41mod builders;
42pub use builders::OpenOptions;
43mod handles;
44pub use handles::{DirHandle, FileHandle};
45mod vfsi;
46pub use vfsi::Vfsi;
47mod extensions;
48pub use extensions::VfsiExt;
49mod metadata;
50pub use metadata::{AttrsOptions, SetAttrsOp};
51mod mkdir;
52pub use mkdir::MkDirOp;
53mod read;
54pub use read::{ReadOp, ReadOptions, ReadResult};
55mod write;
56pub use write::{WriteOp, WriteOptions};
57mod visit;
58pub use visit::{ListDirOptions, WalkOptions};
59mod support;
60pub use support::{
61 DEFAULT_DIRECTORY_MAX_ENTRIES, DEFAULT_DIRECTORY_MAX_PATH_BYTES,
62 DEFAULT_READ_ALLV_MAX_TOTAL_BYTES, DEFAULT_READ_MAX_BYTES, DEFAULT_READ_STREAM_CHUNK_BYTES,
63 DEFAULT_READV_MAX_TOTAL_BYTES, DEFAULT_WALK_MAX_DEPTH, DepthLimit, DirectoryListing,
64 ResourceLimits, StreamCompletion, StreamOptions, TraversalCompletion,
65};
66pub use support::{ReadIntoResult, WriteResult};
67mod listdir;
68mod traversal;
69#[doc(hidden)]
70pub use traversal::walk_events;
71pub use traversal::{WalkControl, WalkEvent, WalkEventKind};
72#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
74pub enum RemoveMode {
75 #[default]
77 Entry,
78 Tree,
80 Contents,
83}
84
85#[doc(hidden)]
87pub mod internal {
88 pub use super::read::{ReadRequest, consume_ops, read_batch};
89 pub use super::support::FsReadResult as OwnedReadResult;
90}
91
92pub mod prelude {
94 pub use super::{
95 AsTarget, Attributes, AttrsOptions, ControlFlow, CopyOptions, DirHandle, FileHandle,
96 ListDirOptions, MkDirOp, OpenFlags, OpenOp, ReadOp, ReadOptions, ReadResult, RemoveMode,
97 RemoveOptions, RenameMode, ResourceLimits, SetAttrsOp, StreamOptions, SyncMode, Target,
98 Vfsi, VfsiExt, WalkOptions, WriteOp, WriteOptions,
99 };
100}
101
102#[derive(Debug)]
107pub enum Target<'a, F> {
108 Path(&'a std::path::Path),
109 File(&'a F),
110}
111impl<F> Copy for Target<'_, F> {}
112impl<F> Clone for Target<'_, F> {
113 fn clone(&self) -> Self {
114 *self
115 }
116}
117impl<F> Target<'_, F> {
118 pub fn path(path: &impl AsRef<std::path::Path>) -> Target<'_, F> {
119 Target::Path(path.as_ref())
120 }
121 pub fn file(file: &F) -> Target<'_, F> {
122 Target::File(file)
123 }
124}
125pub trait AsTarget<F> {
130 fn as_target(&self) -> Target<'_, F>;
131}
132impl<F, P: AsRef<std::path::Path>> AsTarget<F> for P {
133 fn as_target(&self) -> Target<'_, F> {
134 Target::Path(self.as_ref())
135 }
136}
137impl<F> AsTarget<F> for Target<'_, F> {
138 fn as_target(&self) -> Target<'_, F> {
139 match self {
140 Self::Path(path) => Target::Path(path),
141 Self::File(file) => Target::File(file),
142 }
143 }
144}
145
146#[cfg(test)]
147mod target_tests {
148 use super::*;
149 #[test]
150 fn borrowed_targets_and_handle_operations_do_not_require_cloning_handles() {
151 struct NonClone;
152 fn copy<T: Copy>(value: T) -> (T, T) {
153 (value, value)
154 }
155 let file = NonClone;
156 let (first, second) = copy(Target::file(&file));
157 for target in [first, second.as_target()] {
158 assert!(matches!(target, Target::File(actual) if std::ptr::eq(actual, &file)));
159 }
160 let (first, second) = copy(
161 SetAttrsOp::file(&file)
162 .len(0)
163 .with_follow_final_symlink(false),
164 );
165 for op in [first, second] {
166 assert_eq!(op.requested_len(), Some(0));
167 assert!(!op.follow_final_symlink());
168 assert!(matches!(op.target(), Target::File(actual) if std::ptr::eq(*actual, &file)));
169 }
170 let path = std::path::Path::new("/file");
171 let direct: Target<'_, NonClone> = path.as_target();
172 let explicit: Target<'_, NonClone> = Target::path(&path);
173 for target in [direct, explicit] {
174 assert!(matches!(target, Target::Path(actual) if actual == path));
175 }
176 }
177}