1use super::*;
2use crate::io::TokioCompat;
3
4use ::tokio::fs;
5
6use tokio_stream::wrappers::ReadDirStream;
7
8
9
10#[cfg(feature = "tokio-rt")]
12#[cfg_attr(docsrs, doc(cfg(feature = "tokio-rt")))]
13#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)]
14pub struct TokioFs {}
15
16
17#[async_trait]
18impl Filesystem for TokioFs {
19 type ReadDir = ReadDirStream;
20 type DirEntry = fs::DirEntry;
21
22 async fn canonicalize<P: AsRef<Path> + Send>(path: P) -> std::io::Result<PathBuf> {
23 fs::canonicalize(path).await
24 }
25
26 async fn copy<S: AsRef<Path> + Send, D: AsRef<Path> + Send>(
27 from: S,
28 to: D,
29 ) -> std::io::Result<u64> {
30 fs::copy(from, to).await
31 }
32
33 async fn create_dir<P: AsRef<Path> + Send>(path: P) -> std::io::Result<()> {
34 fs::create_dir(path).await
35 }
36
37 async fn create_dir_all<P: AsRef<Path> + Send>(path: P) -> std::io::Result<()> {
38 fs::create_dir_all(path).await
39 }
40
41 async fn hard_link<S: AsRef<Path> + Send, D: AsRef<Path> + Send>(
42 from: S,
43 to: D,
44 ) -> std::io::Result<()> {
45 fs::hard_link(from, to).await
46 }
47
48 async fn metadata<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Metadata> {
49 fs::metadata(path).await
50 }
51
52 async fn read<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Vec<u8>> {
53 fs::read(path).await
54 }
55
56 async fn read_dir<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self::ReadDir> {
57 fs::read_dir(path).await.map(|read_dir| ReadDirStream::new(read_dir))
58 }
59
60 async fn read_link<P: AsRef<Path> + Send>(path: P) -> std::io::Result<PathBuf> {
61 fs::read_link(path).await
62 }
63
64 async fn read_to_string<P: AsRef<Path> + Send>(path: P) -> std::io::Result<String> {
65 fs::read_to_string(path).await
66 }
67
68 async fn remove_dir<P: AsRef<Path> + Send>(path: P) -> std::io::Result<()> {
69 fs::remove_dir(path).await
70 }
71
72 async fn remove_dir_all<P: AsRef<Path> + Send>(path: P) -> std::io::Result<()> {
73 fs::remove_dir(path).await
74 }
75
76 async fn remove_file<P: AsRef<Path> + Send>(path: P) -> std::io::Result<()> {
77 fs::remove_file(path).await
78 }
79
80 async fn rename<O: AsRef<Path> + Send, N: AsRef<Path> + Send>(
81 from: O,
82 to: N,
83 ) -> std::io::Result<()> {
84 fs::rename(from, to).await
85 }
86
87 async fn set_permissions<P: AsRef<Path> + Send>(
88 path: P,
89 perm: Permissions,
90 ) -> std::io::Result<()> {
91 fs::set_permissions(path, perm).await
92 }
93
94 async fn symlink_metadata<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Metadata> {
95 fs::symlink_metadata(path).await
96 }
97
98 async fn write<P: AsRef<Path> + Send, C: AsRef<[u8]> + Send>(
99 path: P,
100 contents: C
101 ) -> std::io::Result<()> {
102 fs::write(path, contents).await
103 }
104}
105
106#[async_trait]
107impl DirEntry for fs::DirEntry {
108 fn path(&self) -> PathBuf {
109 self.path()
110 }
111
112 fn file_name(&self) -> OsString {
113 self.file_name()
114 }
115
116 async fn metadata(&self) -> std::io::Result<Metadata> {
117 self.metadata().await
118 }
119
120 async fn file_type(&self) -> std::io::Result<FileType> {
121 self.file_type().await
122 }
123}
124
125#[async_trait]
126impl File for fs::File {
127 async fn open<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self> {
128 Self::open(path).await
129 }
130
131 async fn create<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self> {
132 Self::create(path).await
133 }
134
135 async fn sync_all(&self) -> std::io::Result<()> {
136 self.sync_all().await
137 }
138
139 async fn sync_data(&self) -> std::io::Result<()> {
140 self.sync_data().await
141 }
142
143 async fn set_len(&self, size: u64) -> std::io::Result<()> {
144 self.set_len(size).await
145 }
146
147 async fn metadata(&self) -> std::io::Result<Metadata> {
148 self.metadata().await
149 }
150
151 async fn set_permissions(&self, perm: Permissions) -> std::io::Result<()> {
152 self.set_permissions(perm).await
153 }
154}
155
156#[async_trait]
157impl File for TokioCompat<fs::File> {
158 async fn open<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self> {
159 fs::File::open(path).await.map(|inner| Self::new(inner))
160 }
161
162 async fn create<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self> {
163 fs::File::create(path).await.map(|inner| Self::new(inner))
164 }
165
166 async fn sync_all(&self) -> std::io::Result<()> {
167 self.get_ref().sync_all().await
168 }
169
170 async fn sync_data(&self) -> std::io::Result<()> {
171 self.get_ref().sync_data().await
172 }
173
174 async fn set_len(&self, size: u64) -> std::io::Result<()> {
175 self.get_ref().set_len(size).await
176 }
177
178 async fn metadata(&self) -> std::io::Result<Metadata> {
179 self.get_ref().metadata().await
180 }
181
182 async fn set_permissions(&self, perm: Permissions) -> std::io::Result<()> {
183 self.get_ref().set_permissions(perm).await
184 }
185}
186
187#[async_trait]
188impl OpenOptions for fs::OpenOptions {
189 type File = TokioCompat<fs::File>;
190
191 fn new() -> Self {
192 Self::new()
193 }
194
195 fn read(&mut self, read: bool) -> &mut Self {
196 self.read(read)
197 }
198
199 fn write(&mut self, write: bool) -> &mut Self {
200 self.write(write)
201 }
202
203 fn append(&mut self, append: bool) -> &mut Self {
204 self.append(append)
205 }
206
207 fn truncate(&mut self, truncate: bool) -> &mut Self {
208 self.truncate(truncate)
209 }
210
211 fn create(&mut self, create: bool) -> &mut Self {
212 self.create(create)
213 }
214
215 fn create_new(&mut self, create_new: bool) -> &mut Self {
216 self.create_new(create_new)
217 }
218
219 async fn open<P: AsRef<Path> + Send>(&self, path: P) -> std::io::Result<Self::File> {
220 self.open(path).await.map(|inner| Self::File::new(inner))
221 }
222}
223
224#[async_trait]
225impl DirBuilder for fs::DirBuilder {
226 fn new() -> Self {
227 Self::new()
228 }
229
230 fn recursive(&mut self, recursive: bool) -> &mut Self {
231 self.recursive(recursive)
232 }
233
234 async fn create<P: AsRef<Path> + Send>(&self, path: P) -> std::io::Result<()> {
235 self.create(path).await
236 }
237}