1use std::ffi::OsString;
2use std::fs::Metadata;
3use std::io;
4use std::path::{Path, PathBuf};
5
6use crate::rt;
7
8pub struct ReadDir {
9 inner: Option<std::fs::ReadDir>,
10}
11
12pub struct DirEntry {
13 pub path: PathBuf,
14 pub file_name: OsString,
15 pub metadata: Metadata,
16}
17
18pub async fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
25 let path = PathBuf::from(path.as_ref());
26 rt::spawn_blocking(move || std::fs::read(path)).await
27}
28
29pub async fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
30 let path = PathBuf::from(path.as_ref());
31 rt::spawn_blocking(move || std::fs::read_to_string(path)).await
32}
33
34pub async fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
35 let path = PathBuf::from(path.as_ref());
36 rt::spawn_blocking(move || std::fs::create_dir_all(path)).await
37}
38
39pub async fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
40 let path = PathBuf::from(path.as_ref());
41 rt::spawn_blocking(move || std::fs::remove_file(path)).await
42}
43
44pub async fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
45 let path = PathBuf::from(path.as_ref());
46 rt::spawn_blocking(move || std::fs::remove_dir(path)).await
47}
48
49pub async fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
50 let path = PathBuf::from(path.as_ref());
51 rt::spawn_blocking(move || std::fs::remove_dir_all(path)).await
52}
53
54pub async fn read_dir(path: PathBuf) -> io::Result<ReadDir> {
55 let read_dir = rt::spawn_blocking(move || std::fs::read_dir(path)).await?;
56
57 Ok(ReadDir {
58 inner: Some(read_dir),
59 })
60}
61
62impl ReadDir {
63 pub async fn next(&mut self) -> io::Result<Option<DirEntry>> {
64 if let Some(mut read_dir) = self.inner.take() {
65 let maybe = rt::spawn_blocking(move || {
66 let entry = read_dir.next().transpose()?;
67
68 entry
69 .map(|entry| -> io::Result<_> {
70 Ok((
71 read_dir,
72 DirEntry {
73 path: entry.path(),
74 file_name: entry.file_name(),
75 metadata: entry.metadata()?,
78 },
79 ))
80 })
81 .transpose()
82 })
83 .await?;
84
85 match maybe {
86 Some((read_dir, entry)) => {
87 self.inner = Some(read_dir);
88 Ok(Some(entry))
89 }
90 None => Ok(None),
91 }
92 } else {
93 Ok(None)
94 }
95 }
96}