monoio/fs/
mod.rs

1//! Filesystem manipulation operations.
2
3mod file;
4use std::{io, path::Path};
5
6pub use file::File;
7
8#[cfg(all(unix, feature = "mkdirat"))]
9mod dir_builder;
10#[cfg(all(unix, feature = "mkdirat"))]
11pub use dir_builder::DirBuilder;
12
13#[cfg(all(unix, feature = "mkdirat"))]
14mod create_dir;
15#[cfg(all(unix, feature = "mkdirat"))]
16pub use create_dir::*;
17
18mod open_options;
19pub use open_options::OpenOptions;
20
21#[cfg(unix)]
22mod metadata;
23#[cfg(unix)]
24pub use metadata::{metadata, symlink_metadata, Metadata};
25
26#[cfg(unix)]
27mod file_type;
28#[cfg(target_os = "linux")]
29pub use file_type::FileType;
30
31#[cfg(unix)]
32mod permissions;
33#[cfg(target_os = "linux")]
34pub use permissions::Permissions;
35
36use crate::buf::IoBuf;
37#[cfg(all(unix, feature = "unlinkat"))]
38use crate::driver::op::Op;
39
40/// Read the entire contents of a file into a bytes vector.
41#[cfg(unix)]
42pub async fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
43    use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd};
44
45    use crate::buf::IoBufMut;
46
47    let file = File::open(path).await?;
48    let sys_file = unsafe { std::fs::File::from_raw_fd(file.as_raw_fd()) };
49    let size = sys_file.metadata()?.len() as usize;
50    let _ = sys_file.into_raw_fd();
51
52    let (res, buf) = file
53        .read_exact_at(Vec::with_capacity(size).slice_mut(0..size), 0)
54        .await;
55    res?;
56    Ok(buf.into_inner())
57}
58
59/// Write a buffer as the entire contents of a file.
60pub async fn write<P: AsRef<Path>, C: IoBuf>(path: P, contents: C) -> (io::Result<()>, C) {
61    let file = match File::create(path).await {
62        Ok(f) => f,
63        Err(e) => return (Err(e), contents),
64    };
65    file.write_all_at(contents, 0).await
66}
67
68/// Removes a file from the filesystem.
69///
70/// Note that there is no
71/// guarantee that the file is immediately deleted (e.g., depending on
72/// platform, other open file descriptors may prevent immediate removal).
73///
74/// # Platform-specific behavior
75///
76/// This function is currently only implemented for Unix.
77///
78/// # Errors
79///
80/// This function will return an error in the following situations, but is not
81/// limited to just these cases:
82///
83/// * `path` points to a directory.
84/// * The file doesn't exist.
85/// * The user lacks permissions to remove the file.
86///
87/// # Examples
88///
89/// ```no_run
90/// use monoio::fs::File;
91///
92/// #[monoio::main]
93/// async fn main() -> std::io::Result<()> {
94///     fs::remove_file("a.txt").await?;
95///     Ok(())
96/// }
97/// ```
98#[cfg(all(unix, feature = "unlinkat"))]
99pub async fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
100    Op::unlink(path)?.await.meta.result?;
101    Ok(())
102}
103
104/// Removes an empty directory.
105///
106/// # Platform-specific behavior
107///
108/// This function is currently only implemented for Unix.
109///
110/// # Errors
111///
112/// This function will return an error in the following situations, but is not
113/// limited to just these cases:
114///
115/// * `path` doesn't exist.
116/// * `path` isn't a directory.
117/// * The user lacks permissions to remove the directory at the provided `path`.
118/// * The directory isn't empty.
119///
120/// # Examples
121///
122/// ```no_run
123/// use monoio::fs::File;
124///
125/// #[monoio::main]
126/// async fn main() -> std::io::Result<()> {
127///     fs::remove_dir("/some/dir").await?;
128///     Ok(())
129/// }
130/// ```
131#[cfg(all(unix, feature = "unlinkat"))]
132pub async fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
133    Op::rmdir(path)?.await.meta.result?;
134    Ok(())
135}
136
137/// Rename a file or directory to a new name, replacing the original file if
138/// `to` already exists.
139///
140/// This will not work if the new name is on a different mount point.
141///
142/// This is async version of [std::fs::rename].
143///
144/// # Errors
145///
146/// This function will return an error in the following situations, but is not
147/// limited to just these cases:
148///
149/// * `from` does not exist.
150/// * The user lacks permissions to view contents.
151/// * `from` and `to` are on separate filesystems.
152///
153/// # Examples
154///
155/// ```no_run
156/// use monoio::fs;
157///
158/// #[monoio::main]
159/// async fn main() -> std::io::Result<()> {
160///     fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt
161///     Ok(())
162/// }
163/// ```
164#[cfg(all(unix, feature = "renameat"))]
165pub async fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
166    Op::rename(from.as_ref(), to.as_ref())?.await.meta.result?;
167    Ok(())
168}