pub type Result<T> = crate::VfResult<T>;
pub type Error = crate::VfError;
pub use crate::{
AttrMask as Attributes, Attrs, Capabilities, CopyOptions, DirEntry, ErrorDomain,
FilesystemStats, FsObjId, OpenFlags, OpenOp, Permissions, RemoveOptions, StatusCode,
TransportKind, VfType as FileType,
};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum RenameMode {
#[default]
Replace,
NoReplace,
Exchange,
}
pub use std::io::ErrorKind;
pub use std::ops::ControlFlow;
mod io;
pub use io::SyncMode;
mod builders;
pub use builders::OpenOptions;
mod handles;
pub use handles::{DirHandle, FileHandle};
mod vfsi;
pub use vfsi::Vfsi;
mod extensions;
pub use extensions::VfsiExt;
mod metadata;
pub use metadata::{AttrsOptions, SetAttrsOp};
mod mkdir;
pub use mkdir::MkDirOp;
mod read;
pub use read::{ReadOp, ReadOptions, ReadResult};
mod write;
pub use write::{WriteOp, WriteOptions};
mod visit;
pub use visit::ListDirOptions;
mod support;
pub use support::{
DEFAULT_DIRECTORY_MAX_ENTRIES, DEFAULT_DIRECTORY_MAX_PATH_BYTES,
DEFAULT_READ_ALLV_MAX_TOTAL_BYTES, DEFAULT_READ_MAX_BYTES, DEFAULT_READ_STREAM_CHUNK_BYTES,
DEFAULT_READV_MAX_TOTAL_BYTES, DEFAULT_WALK_MAX_DEPTH, DepthLimit, DirectoryListing,
ResourceLimits, StreamCompletion, StreamOptions, TraversalCompletion,
};
pub use support::{ReadIntoResult, WriteResult};
mod listdir;
mod traversal;
#[doc(hidden)]
pub use traversal::walk_events;
pub use traversal::{WalkControl, WalkEvent, WalkEventKind};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum RemoveMode {
#[default]
Entry,
Tree,
Contents,
}
#[doc(hidden)]
pub mod internal {
pub use super::read::{ReadRequest, consume_ops, read_batch};
pub use super::support::FsReadResult as OwnedReadResult;
}
pub mod prelude {
pub use super::{
AsTarget, Attributes, AttrsOptions, ControlFlow, CopyOptions, DirHandle, FileHandle,
ListDirOptions, MkDirOp, OpenFlags, OpenOp, ReadOp, ReadOptions, ReadResult, RemoveMode,
RemoveOptions, RenameMode, ResourceLimits, SetAttrsOp, StreamOptions, SyncMode, Target,
Vfsi, VfsiExt, WriteOp, WriteOptions,
};
}
#[derive(Debug)]
pub enum Target<'a, F> {
Path(&'a std::path::Path),
File(&'a F),
}
impl<F> Copy for Target<'_, F> {}
impl<F> Clone for Target<'_, F> {
fn clone(&self) -> Self {
*self
}
}
impl<F> Target<'_, F> {
pub fn path(path: &impl AsRef<std::path::Path>) -> Target<'_, F> {
Target::Path(path.as_ref())
}
pub fn file(file: &F) -> Target<'_, F> {
Target::File(file)
}
}
pub trait AsTarget<F> {
fn as_target(&self) -> Target<'_, F>;
}
impl<F, P: AsRef<std::path::Path>> AsTarget<F> for P {
fn as_target(&self) -> Target<'_, F> {
Target::Path(self.as_ref())
}
}
impl<F> AsTarget<F> for Target<'_, F> {
fn as_target(&self) -> Target<'_, F> {
match self {
Self::Path(path) => Target::Path(path),
Self::File(file) => Target::File(file),
}
}
}
#[cfg(test)]
mod target_tests {
use super::*;
#[test]
fn borrowed_targets_and_handle_operations_do_not_require_cloning_handles() {
struct NonClone;
fn copy<T: Copy>(value: T) -> (T, T) {
(value, value)
}
let file = NonClone;
let (first, second) = copy(Target::file(&file));
for target in [first, second.as_target()] {
assert!(matches!(target, Target::File(actual) if std::ptr::eq(actual, &file)));
}
let (first, second) = copy(
SetAttrsOp::file(&file)
.len(0)
.with_follow_final_symlink(false),
);
for op in [first, second] {
assert_eq!(op.requested_len(), Some(0));
assert!(!op.follow_final_symlink());
assert!(matches!(op.target(), Target::File(actual) if std::ptr::eq(*actual, &file)));
}
let path = std::path::Path::new("/file");
let direct: Target<'_, NonClone> = path.as_target();
let explicit: Target<'_, NonClone> = Target::path(&path);
for target in [direct, explicit] {
assert!(matches!(target, Target::Path(actual) if actual == path));
}
}
}