1use crate::io::{Error, Result};
4use crate::Wrapper;
5
6use std::fmt::Arguments;
7use std::io::{Read, Seek, SeekFrom, Write};
8use std::ops::{Deref, DerefMut};
9use std::path::{Path, PathBuf};
10use std::time::SystemTime;
11
12pub struct DirBuilder(::std::fs::DirBuilder);
13
14impl DirBuilder {
15 pub fn new() -> Self {
16 DirBuilder(::std::fs::DirBuilder::new())
17 }
18
19 pub fn recursive(&mut self, recursive: bool) -> &mut Self {
20 self.0.recursive(recursive);
21
22 self
23 }
24
25 pub fn create<P: AsRef<Path>>(&self, path: P) -> Result<()> {
26 let path = path.as_ref();
27
28 self.0.create(path).map_err(|x| {
29 Error::Filesystem(path.to_owned(), "creating directory", x)
30 })
31 }
32}
33
34impl Deref for DirBuilder {
35 type Target = ::std::fs::DirBuilder;
36
37 fn deref(&self) -> &Self::Target {
38 &self.0
39 }
40}
41
42impl DerefMut for DirBuilder {
43 fn deref_mut(&mut self) -> &mut Self::Target {
44 &mut self.0
45 }
46}
47
48impl Wrapper<::std::fs::DirBuilder> for DirBuilder {
49 fn into_inner(self) -> ::std::fs::DirBuilder {
50 self.0
51 }
52}
53
54pub struct DirEntry(::std::fs::DirEntry);
55
56impl DirEntry {
57 fn new(inner: ::std::fs::DirEntry) -> Self {
58 DirEntry(inner)
59 }
60
61 pub fn metadata(&self) -> Result<Metadata> {
62 self.0
63 .metadata()
64 .map(|x| Metadata::new(x, self.0.path()))
65 .map_err(|x| {
66 Error::Filesystem(self.0.path(), "getting metadata from", x)
67 })
68 }
69
70 pub fn file_type(&self) -> Result<FileType> {
71 self.0.file_type().map_err(|x| {
72 Error::Filesystem(self.0.path(), "getting the file type of", x)
73 })
74 }
75}
76
77impl Deref for DirEntry {
78 type Target = ::std::fs::DirEntry;
79
80 fn deref(&self) -> &Self::Target {
81 &self.0
82 }
83}
84
85impl DerefMut for DirEntry {
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 &mut self.0
88 }
89}
90
91impl Wrapper<::std::fs::DirEntry> for DirEntry {
92 fn into_inner(self) -> ::std::fs::DirEntry {
93 self.0
94 }
95}
96
97pub struct File {
98 inner: ::std::fs::File,
99 path: PathBuf,
101}
102
103impl File {
104 fn new(inner: ::std::fs::File, path: PathBuf) -> Self {
105 File { inner, path }
106 }
107
108 pub fn create<P: AsRef<Path>>(path: P) -> Result<File> {
109 let path = path.as_ref().to_owned();
110 let inner = ::std::fs::File::create(&path)
111 .map_err(|x| Error::Filesystem(path.clone(), "creating file", x))?;
112
113 Ok(Self::new(inner, path))
114 }
115
116 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
117 let path = path.as_ref().to_owned();
118 let inner = ::std::fs::File::open(&path)
119 .map_err(|x| Error::Filesystem(path.clone(), "opening file", x))?;
120
121 Ok(Self::new(inner, path))
122 }
123
124 pub fn sync_all(&self) -> Result<()> {
125 self.inner
126 .sync_all()
127 .map_err(|x| Error::Filesystem(self.path.clone(), "synching", x))
128 }
129
130 pub fn sync_data(&self) -> Result<()> {
131 self.inner.sync_data().map_err(|x| {
132 Error::Filesystem(self.path.clone(), "synching data of", x)
133 })
134 }
135
136 pub fn set_len(&self, size: u64) -> Result<()> {
137 self.inner.set_len(size).map_err(|x| {
138 Error::Filesystem(self.path.clone(), "setting the length of", x)
139 })
140 }
141
142 pub fn metadata(&self) -> Result<Metadata> {
143 self.inner
144 .metadata()
145 .map(|x| Metadata::new(x, self.path.clone()))
146 .map_err(|x| {
147 Error::Filesystem(self.path.clone(), "getting metadata from", x)
148 })
149 }
150
151 pub fn try_clone(&self) -> Result<File> {
152 self.inner
153 .try_clone()
154 .map(|x| File::new(x, self.path.clone()))
155 .map_err(|x| {
156 Error::Filesystem(self.path.clone(), "cloning handle for", x)
157 })
158 }
159
160 pub fn set_permissions(&self, perm: Permissions) -> Result<()> {
161 self.inner.set_permissions(perm).map_err(|x| {
163 Error::Filesystem(self.path.clone(), "setting permissions for", x)
164 })
165 }
166}
167
168impl Read for File {
169 fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result<usize> {
170 self.inner.read(buf).map_err(|x| {
171 ::std::io::Error::new(
172 x.kind(),
173 Error::Filesystem(self.path.clone(), "reading", x),
174 )
175 })
176 }
177
178 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> ::std::io::Result<usize> {
179 self.inner.read_to_end(buf).map_err(|x| {
180 ::std::io::Error::new(
181 x.kind(),
182 Error::Filesystem(self.path.clone(), "reading", x),
183 )
184 })
185 }
186
187 fn read_to_string(&mut self, buf: &mut String) -> ::std::io::Result<usize> {
188 self.inner.read_to_string(buf).map_err(|x| {
189 ::std::io::Error::new(
190 x.kind(),
191 Error::Filesystem(self.path.clone(), "reading", x),
192 )
193 })
194 }
195
196 fn read_exact(&mut self, buf: &mut [u8]) -> ::std::io::Result<()> {
197 self.inner.read_exact(buf).map_err(|x| {
198 ::std::io::Error::new(
199 x.kind(),
200 Error::Filesystem(self.path.clone(), "reading", x),
201 )
202 })
203 }
204}
205
206impl Write for File {
207 fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> {
208 self.inner.write(buf).map_err(|x| {
209 ::std::io::Error::new(
210 x.kind(),
211 Error::Filesystem(self.path.clone(), "writing", x),
212 )
213 })
214 }
215
216 fn flush(&mut self) -> ::std::io::Result<()> {
217 self.inner.flush().map_err(|x| {
218 ::std::io::Error::new(
219 x.kind(),
220 Error::Filesystem(self.path.clone(), "flushing", x),
221 )
222 })
223 }
224
225 fn write_all(&mut self, buf: &[u8]) -> ::std::io::Result<()> {
226 self.inner.write_all(buf).map_err(|x| {
227 ::std::io::Error::new(
228 x.kind(),
229 Error::Filesystem(self.path.clone(), "writing", x),
230 )
231 })
232 }
233
234 fn write_fmt(&mut self, fmt: Arguments) -> ::std::io::Result<()> {
235 self.inner.write_fmt(fmt).map_err(|x| {
236 ::std::io::Error::new(
237 x.kind(),
238 Error::Filesystem(self.path.clone(), "writing", x),
239 )
240 })
241 }
242}
243
244impl Seek for File {
245 fn seek(&mut self, pos: SeekFrom) -> ::std::io::Result<u64> {
246 self.inner.seek(pos).map_err(|x| {
247 ::std::io::Error::new(
248 x.kind(),
249 Error::Filesystem(self.path.clone(), "seeking", x),
250 )
251 })
252 }
253}
254
255impl Deref for File {
256 type Target = ::std::fs::File;
257
258 fn deref(&self) -> &Self::Target {
259 &self.inner
260 }
261}
262
263impl DerefMut for File {
264 fn deref_mut(&mut self) -> &mut Self::Target {
265 &mut self.inner
266 }
267}
268
269impl Wrapper<::std::fs::File> for File {
270 fn into_inner(self) -> ::std::fs::File {
271 self.inner
272 }
273}
274
275pub type FileType = ::std::fs::FileType;
276
277pub struct Metadata {
278 inner: ::std::fs::Metadata,
279 path: PathBuf,
280}
281
282impl Metadata {
283 fn new(inner: ::std::fs::Metadata, path: PathBuf) -> Self {
284 Self { inner, path }
285 }
286
287 pub fn modified(&self) -> Result<SystemTime> {
288 self.inner.modified().map_err(|x| {
289 Error::Filesystem(
290 self.path.to_owned(),
291 "getting the modification time of",
292 x,
293 )
294 })
295 }
296
297 pub fn accessed(&self) -> Result<SystemTime> {
298 self.inner.accessed().map_err(|x| {
299 Error::Filesystem(
300 self.path.to_owned(),
301 "getting the access time of",
302 x,
303 )
304 })
305 }
306
307 pub fn created(&self) -> Result<SystemTime> {
308 self.inner.created().map_err(|x| {
309 Error::Filesystem(
310 self.path.to_owned(),
311 "getting the creation time of",
312 x,
313 )
314 })
315 }
316}
317
318impl Deref for Metadata {
319 type Target = ::std::fs::Metadata;
320
321 fn deref(&self) -> &Self::Target {
322 &self.inner
323 }
324}
325
326impl DerefMut for Metadata {
327 fn deref_mut(&mut self) -> &mut Self::Target {
328 &mut self.inner
329 }
330}
331
332impl Wrapper<::std::fs::Metadata> for Metadata {
333 fn into_inner(self) -> ::std::fs::Metadata {
334 self.inner
335 }
336}
337
338pub struct OpenOptions(::std::fs::OpenOptions);
339
340impl OpenOptions {
341 pub fn new() -> Self {
342 OpenOptions(::std::fs::OpenOptions::new())
343 }
344
345 pub fn read(&mut self, read: bool) -> &mut Self {
346 self.0.read(read);
347
348 self
349 }
350
351 pub fn write(&mut self, write: bool) -> &mut Self {
352 self.0.write(write);
353
354 self
355 }
356
357 pub fn append(&mut self, append: bool) -> &mut Self {
358 self.0.append(append);
359
360 self
361 }
362
363 pub fn truncate(&mut self, truncate: bool) -> &mut Self {
364 self.0.truncate(truncate);
365
366 self
367 }
368
369 pub fn create(&mut self, create: bool) -> &mut Self {
370 self.0.create(create);
371
372 self
373 }
374
375 pub fn create_new(&mut self, create_new: bool) -> &mut Self {
376 self.0.create_new(create_new);
377
378 self
379 }
380
381 pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<File> {
382 let path = path.as_ref();
383
384 self.0
386 .open(path)
387 .map(|x| File::new(x, path.to_owned()))
388 .map_err(|x| Error::Filesystem(path.to_owned(), "opening file", x))
389 }
390}
391
392impl Deref for OpenOptions {
393 type Target = ::std::fs::OpenOptions;
394
395 fn deref(&self) -> &Self::Target {
396 &self.0
397 }
398}
399
400impl DerefMut for OpenOptions {
401 fn deref_mut(&mut self) -> &mut Self::Target {
402 &mut self.0
403 }
404}
405
406impl Wrapper<::std::fs::OpenOptions> for OpenOptions {
407 fn into_inner(self) -> ::std::fs::OpenOptions {
408 self.0
409 }
410}
411
412pub type Permissions = ::std::fs::Permissions;
413
414pub struct ReadDir {
415 inner: ::std::fs::ReadDir,
416 path: PathBuf,
417}
418
419impl ReadDir {
420 fn new(inner: ::std::fs::ReadDir, path: PathBuf) -> Self {
421 Self { inner, path }
422 }
423}
424
425impl Iterator for ReadDir {
426 type Item = Result<DirEntry>;
427
428 fn next(&mut self) -> Option<Self::Item> {
429 self.inner.next().map(|x| {
430 x.map(DirEntry::new).map_err(|err| {
431 Error::Filesystem(
432 self.path.to_owned(),
433 "iterating through directory",
434 err,
435 )
436 })
437 })
438 }
439}
440
441impl Deref for ReadDir {
442 type Target = ::std::fs::ReadDir;
443
444 fn deref(&self) -> &Self::Target {
445 &self.inner
446 }
447}
448
449impl DerefMut for ReadDir {
450 fn deref_mut(&mut self) -> &mut Self::Target {
451 &mut self.inner
452 }
453}
454
455impl Wrapper<::std::fs::ReadDir> for ReadDir {
456 fn into_inner(self) -> ::std::fs::ReadDir {
457 self.inner
458 }
459}
460
461pub fn canonicalize<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
462 let path = path.as_ref();
463
464 ::std::fs::canonicalize(path)
465 .map_err(|x| Error::Filesystem(path.to_owned(), "canonicalizing", x))
466}
467
468pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<u64> {
469 let from = from.as_ref();
470 let to = to.as_ref();
471
472 ::std::fs::copy(from, to).map_err(|x| {
473 Error::Filesystem2(from.to_owned(), to.to_owned(), "copying file", x)
474 })
475}
476
477pub fn create_dir<P: AsRef<Path>>(path: P) -> Result<()> {
478 let path = path.as_ref();
479
480 ::std::fs::create_dir(path).map_err(|x| {
481 Error::Filesystem(path.to_owned(), "creating directory", x)
482 })
483}
484
485pub fn create_dir_all<P: AsRef<Path>>(path: P) -> Result<()> {
486 let path = path.as_ref();
487
488 ::std::fs::create_dir_all(path).map_err(|x| {
489 Error::Filesystem(path.to_owned(), "recursively creating directory", x)
490 })
491}
492
493pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> Result<()> {
494 let src = src.as_ref();
495 let dst = dst.as_ref();
496
497 ::std::fs::hard_link(src, dst).map_err(|x| {
498 Error::Filesystem2(src.to_owned(), dst.to_owned(), "hard linking", x)
499 })
500}
501
502pub fn metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
503 let path = path.as_ref();
504
505 ::std::fs::metadata(path)
506 .map(|x| Metadata::new(x, path.to_owned()))
507 .map_err(|x| {
508 Error::Filesystem(path.to_owned(), "getting metadata from", x)
509 })
510}
511
512pub fn read<P: AsRef<Path>>(path: P) -> Result<Vec<u8>> {
513 let path = path.as_ref();
514
515 ::std::fs::read(path)
516 .map_err(|x| Error::Filesystem(path.to_owned(), "reading", x))
517}
518
519pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<ReadDir> {
520 let path = path.as_ref();
521
522 ::std::fs::read_dir(path)
523 .map(|x| ReadDir::new(x, path.to_owned()))
524 .map_err(|x| Error::Filesystem(path.to_owned(), "reading directory", x))
525}
526
527pub fn read_link<P: AsRef<Path>>(path: P) -> Result<PathBuf> {
528 let path = path.as_ref();
529
530 ::std::fs::read_link(path)
531 .map_err(|x| Error::Filesystem(path.to_owned(), "reading link", x))
532}
533
534pub fn read_to_string<P: AsRef<Path>>(path: P) -> Result<String> {
535 let path = path.as_ref();
536
537 ::std::fs::read_to_string(path)
538 .map_err(|x| Error::Filesystem(path.to_owned(), "reading", x))
539}
540
541pub fn remove_dir<P: AsRef<Path>>(path: P) -> Result<()> {
542 let path = path.as_ref();
543
544 ::std::fs::remove_dir(path).map_err(|x| {
545 Error::Filesystem(path.to_owned(), "removing directory", x)
546 })
547}
548
549pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> Result<()> {
550 let path = path.as_ref();
551
552 ::std::fs::remove_dir_all(path).map_err(|x| {
553 Error::Filesystem(path.to_owned(), "recursively removing directory", x)
554 })
555}
556
557pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<()> {
558 let path = path.as_ref();
559
560 ::std::fs::remove_file(path)
561 .map_err(|x| Error::Filesystem(path.to_owned(), "removing file", x))
562}
563
564pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<()> {
565 let from = from.as_ref();
566 let to = to.as_ref();
567
568 ::std::fs::rename(from, to).map_err(|x| {
569 Error::Filesystem2(from.to_owned(), to.to_owned(), "renaming", x)
570 })
571}
572
573pub fn set_permissions<P: AsRef<Path>>(
574 path: P,
575 perm: Permissions,
576) -> Result<()> {
577 let path = path.as_ref();
578
579 ::std::fs::set_permissions(path, perm).map_err(|x| {
581 Error::Filesystem(path.to_owned(), "setting permissions for", x)
582 })
583}
584
585pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> Result<()> {
586 let src = src.as_ref();
587 let dst = dst.as_ref();
588
589 #[allow(deprecated)]
590 ::std::fs::soft_link(src, dst).map_err(|x| {
591 Error::Filesystem2(src.to_owned(), dst.to_owned(), "soft linking", x)
592 })
593}
594
595pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
596 let path = path.as_ref();
597
598 ::std::fs::metadata(path)
599 .map(|x| Metadata::new(x, path.to_owned()))
600 .map_err(|x| {
601 Error::Filesystem(
602 path.to_owned(),
603 "getting symlink metadata from",
604 x,
605 )
606 })
607}
608
609pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(
610 path: P,
611 contents: C,
612) -> Result<()> {
613 let path = path.as_ref();
614
615 ::std::fs::write(path, contents)
616 .map_err(|x| Error::Filesystem(path.to_owned(), "writing", x))
617}