1mod dir_entry;
4mod file;
5
6pub use dir_entry::*;
7pub use file::*;
8
9use futures::{AsyncReadExt, AsyncWriteExt, Stream};
10use std::{
11 fs::{Metadata, OpenOptions, Permissions},
12 future::Future,
13 path::{Path, PathBuf},
14 pin::pin,
15};
16
17pub trait FSRuntime: Send + Sync {
19 type File: RuntimeFile<Runtime = Self>;
21 type DirEntry: RuntimeDirEntry;
23
24 fn canonicalize(
29 &self,
30 path: impl AsRef<Path> + Send,
31 ) -> impl Future<Output = std::io::Result<PathBuf>> + Send;
32
33 fn copy(
38 &self,
39 from: impl AsRef<Path> + Send,
40 to: impl AsRef<Path> + Send,
41 ) -> impl Future<Output = std::io::Result<u64>> + Send;
42
43 fn create_dir(
47 &self,
48 path: impl AsRef<Path> + Send,
49 ) -> impl Future<Output = std::io::Result<()>> + Send;
50
51 fn create_dir_all(
56 &self,
57 path: impl AsRef<Path> + Send,
58 ) -> impl Future<Output = std::io::Result<()>> + Send;
59
60 fn remove_dir(
64 &self,
65 path: impl AsRef<Path> + Send,
66 ) -> impl Future<Output = std::io::Result<()>> + Send;
67
68 fn remove_dir_all(
72 &self,
73 path: impl AsRef<Path> + Send,
74 ) -> impl Future<Output = std::io::Result<()>> + Send;
75
76 fn read_dir(
80 &self,
81 path: impl AsRef<Path> + Send,
82 ) -> impl Future<
83 Output = std::io::Result<impl Stream<Item = std::io::Result<Self::DirEntry>> + Send>,
84 > + Send;
85
86 fn read_link(
90 &self,
91 path: impl AsRef<Path> + Send,
92 ) -> impl Future<Output = std::io::Result<PathBuf>> + Send;
93
94 #[cfg(any(unix, doc))]
98 #[cfg_attr(docsrs, doc(cfg(unix)))]
99 fn symlink(
100 &self,
101 from: impl AsRef<Path> + Send,
102 to: impl AsRef<Path> + Send,
103 ) -> impl Future<Output = std::io::Result<()>> + Send;
104
105 #[cfg(any(windows, doc))]
109 #[cfg_attr(docsrs, doc(cfg(windows)))]
110 fn symlink_dir(
111 &self,
112 from: impl AsRef<Path> + Send,
113 to: impl AsRef<Path> + Send,
114 ) -> impl Future<Output = std::io::Result<()>> + Send;
115
116 #[cfg(any(windows, doc))]
120 #[cfg_attr(docsrs, doc(cfg(windows)))]
121 fn symlink_file(
122 &self,
123 from: impl AsRef<Path>,
124 to: impl AsRef<Path> + Send,
125 ) -> impl Future<Output = std::io::Result<()>> + Send;
126
127 fn hard_link(
131 &self,
132 from: impl AsRef<Path> + Send,
133 to: impl AsRef<Path> + Send,
134 ) -> impl Future<Output = std::io::Result<()>> + Send;
135
136 fn metadata(
141 &self,
142 path: impl AsRef<Path> + Send,
143 ) -> impl Future<Output = std::io::Result<Metadata>> + Send;
144
145 fn read(
149 &self,
150 path: impl AsRef<Path> + Send,
151 ) -> impl Future<Output = std::io::Result<Vec<u8>>> + Send {
152 async {
153 let mut file = pin!(Self::File::open(self, OpenOptions::new().read(true), path).await?);
154 let file_size: usize = file
155 .metadata()
156 .await?
157 .len()
158 .try_into()
159 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err))?;
160
161 let mut buffer = Vec::with_capacity(file_size);
162 file.read_to_end(&mut buffer).await?;
163
164 Ok(buffer)
165 }
166 }
167
168 fn read_to_string(
172 &self,
173 path: impl AsRef<Path> + Send,
174 ) -> impl Future<Output = std::io::Result<String>> + Send {
175 async {
176 let mut file = pin!(Self::File::open(self, OpenOptions::new().read(true), path).await?);
177 let file_size: usize = file
178 .metadata()
179 .await?
180 .len()
181 .try_into()
182 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err))?;
183
184 let mut buffer = String::with_capacity(file_size);
185 file.read_to_string(&mut buffer).await?;
186
187 Ok(buffer)
188 }
189 }
190
191 fn write(
195 &self,
196 path: impl AsRef<Path> + Send,
197 content: &[u8],
198 ) -> impl Future<Output = std::io::Result<()>> + Send {
199 async {
200 let mut file =
201 pin!(Self::File::open(self, OpenOptions::new().create(true), path).await?);
202 file.write_all(content).await
203 }
204 }
205
206 fn remove_file(
210 &self,
211 path: impl AsRef<Path> + Send,
212 ) -> impl Future<Output = std::io::Result<()>> + Send;
213
214 fn rename(
219 &self,
220 from: impl AsRef<Path> + Send,
221 to: impl AsRef<Path> + Send,
222 ) -> impl Future<Output = std::io::Result<()>> + Send;
223
224 fn set_permissions(
228 &self,
229 path: impl AsRef<Path> + Send,
230 permissions: Permissions,
231 ) -> impl Future<Output = std::io::Result<()>> + Send;
232
233 fn symlink_metadata(
237 &self,
238 path: impl AsRef<Path> + Send,
239 ) -> impl Future<Output = std::io::Result<Metadata>> + Send;
240}