1use super::{
2 parse_response, vfs_request, FileMetadata, SeekFrom, VfsAction, VfsError, VfsResponse,
3};
4use crate::{get_blob, PackageId};
5
6pub struct File {
10 pub path: String,
11 pub timeout: u64,
12}
13
14impl File {
15 pub fn new<T: Into<String>>(path: T, timeout: u64) -> Self {
17 Self {
18 path: path.into(),
19 timeout,
20 }
21 }
22
23 pub fn read(&self) -> Result<Vec<u8>, VfsError> {
26 let message = vfs_request(&self.path, VfsAction::Read)
27 .send_and_await_response(self.timeout)
28 .unwrap()
29 .map_err(|e| VfsError::SendError(e.kind))?;
30
31 match parse_response(message.body())? {
32 VfsResponse::Read => {
33 let data = match get_blob() {
34 Some(bytes) => bytes.bytes,
35 None => {
36 return Err(VfsError::ParseError {
37 error: "no blob".to_string(),
38 path: self.path.clone(),
39 })
40 }
41 };
42 Ok(data)
43 }
44 VfsResponse::Err(e) => Err(e.into()),
45 _ => Err(VfsError::ParseError {
46 error: "unexpected response".to_string(),
47 path: self.path.clone(),
48 }),
49 }
50 }
51
52 pub fn read_into(&self, buffer: &mut [u8]) -> Result<usize, VfsError> {
55 let message = vfs_request(&self.path, VfsAction::Read)
56 .send_and_await_response(self.timeout)
57 .unwrap()
58 .map_err(|e| VfsError::SendError(e.kind))?;
59
60 match parse_response(message.body())? {
61 VfsResponse::Read => {
62 let data = get_blob().unwrap_or_default().bytes;
63 let len = std::cmp::min(data.len(), buffer.len());
64 buffer[..len].copy_from_slice(&data[..len]);
65 Ok(len)
66 }
67 VfsResponse::Err(e) => Err(e.into()),
68 _ => Err(VfsError::ParseError {
69 error: "unexpected response".to_string(),
70 path: self.path.clone(),
71 }),
72 }
73 }
74
75 pub fn read_at(&self, buffer: &mut [u8]) -> Result<usize, VfsError> {
78 let length = buffer.len() as u64;
79
80 let message = vfs_request(&self.path, VfsAction::ReadExact { length })
81 .send_and_await_response(self.timeout)
82 .unwrap()
83 .map_err(|e| VfsError::SendError(e.kind))?;
84
85 match parse_response(message.body())? {
86 VfsResponse::Read => {
87 let data = get_blob().unwrap_or_default().bytes;
88 let len = std::cmp::min(data.len(), buffer.len());
89 buffer[..len].copy_from_slice(&data[..len]);
90 Ok(len)
91 }
92 VfsResponse::Err(e) => Err(e.into()),
93 _ => Err(VfsError::ParseError {
94 error: "unexpected response".to_string(),
95 path: self.path.clone(),
96 }),
97 }
98 }
99
100 pub fn read_to_end(&self) -> Result<Vec<u8>, VfsError> {
103 let message = vfs_request(&self.path, VfsAction::ReadToEnd)
104 .send_and_await_response(self.timeout)
105 .unwrap()
106 .map_err(|e| VfsError::SendError(e.kind))?;
107
108 match parse_response(message.body())? {
109 VfsResponse::Read => Ok(get_blob().unwrap_or_default().bytes),
110 VfsResponse::Err(e) => Err(e),
111 _ => Err(VfsError::ParseError {
112 error: "unexpected response".to_string(),
113 path: self.path.clone(),
114 }),
115 }
116 }
117
118 pub fn read_to_string(&self) -> Result<String, VfsError> {
122 let message = vfs_request(&self.path, VfsAction::ReadToString)
123 .send_and_await_response(self.timeout)
124 .unwrap()
125 .map_err(|e| VfsError::SendError(e.kind))?;
126
127 match parse_response(message.body())? {
128 VfsResponse::ReadToString(s) => Ok(s),
129 VfsResponse::Err(e) => Err(e),
130 _ => Err(VfsError::ParseError {
131 error: "unexpected response".to_string(),
132 path: self.path.clone(),
133 }),
134 }
135 }
136
137 pub fn write(&self, buffer: &[u8]) -> Result<(), VfsError> {
140 let message = vfs_request(&self.path, VfsAction::Write)
141 .blob_bytes(buffer)
142 .send_and_await_response(self.timeout)
143 .unwrap()
144 .map_err(|e| VfsError::SendError(e.kind))?;
145
146 match parse_response(message.body())? {
147 VfsResponse::Ok => Ok(()),
148 VfsResponse::Err(e) => Err(e),
149 _ => Err(VfsError::ParseError {
150 error: "unexpected response".to_string(),
151 path: self.path.clone(),
152 }),
153 }
154 }
155
156 pub fn write_all(&mut self, buffer: &[u8]) -> Result<(), VfsError> {
158 let message = vfs_request(&self.path, VfsAction::WriteAll)
159 .blob_bytes(buffer)
160 .send_and_await_response(self.timeout)
161 .unwrap()
162 .map_err(|e| VfsError::SendError(e.kind))?;
163
164 match parse_response(message.body())? {
165 VfsResponse::Ok => Ok(()),
166 VfsResponse::Err(e) => Err(e),
167 _ => Err(VfsError::ParseError {
168 error: "unexpected response".to_string(),
169 path: self.path.clone(),
170 }),
171 }
172 }
173
174 pub fn append(&mut self, buffer: &[u8]) -> Result<(), VfsError> {
176 let message = vfs_request(&self.path, VfsAction::Append)
177 .blob_bytes(buffer)
178 .send_and_await_response(self.timeout)
179 .unwrap()
180 .map_err(|e| VfsError::SendError(e.kind))?;
181
182 match parse_response(message.body())? {
183 VfsResponse::Ok => Ok(()),
184 VfsResponse::Err(e) => Err(e),
185 _ => Err(VfsError::ParseError {
186 error: "unexpected response".to_string(),
187 path: self.path.clone(),
188 }),
189 }
190 }
191
192 pub fn seek(&mut self, pos: SeekFrom) -> Result<u64, VfsError> {
195 let message = vfs_request(&self.path, VfsAction::Seek(pos))
196 .send_and_await_response(self.timeout)
197 .unwrap()
198 .map_err(|e| VfsError::SendError(e.kind))?;
199
200 match parse_response(message.body())? {
201 VfsResponse::SeekFrom {
202 new_offset: new_pos,
203 } => Ok(new_pos),
204 VfsResponse::Err(e) => Err(e),
205 _ => Err(VfsError::ParseError {
206 error: "unexpected response".to_string(),
207 path: self.path.clone(),
208 }),
209 }
210 }
211
212 pub fn copy(&mut self, path: &str) -> Result<File, VfsError> {
214 let message = vfs_request(
215 &self.path,
216 VfsAction::CopyFile {
217 new_path: path.to_string(),
218 },
219 )
220 .send_and_await_response(self.timeout)
221 .unwrap()
222 .map_err(|e| VfsError::SendError(e.kind))?;
223
224 match parse_response(message.body())? {
225 VfsResponse::Ok => Ok(File {
226 path: path.to_string(),
227 timeout: self.timeout,
228 }),
229 VfsResponse::Err(e) => Err(e),
230 _ => Err(VfsError::ParseError {
231 error: "unexpected response".to_string(),
232 path: self.path.clone(),
233 }),
234 }
235 }
236
237 pub fn set_len(&mut self, size: u64) -> Result<(), VfsError> {
239 let message = vfs_request(&self.path, VfsAction::SetLen(size))
240 .send_and_await_response(self.timeout)
241 .unwrap()
242 .map_err(|e| VfsError::SendError(e.kind))?;
243
244 match parse_response(message.body())? {
245 VfsResponse::Ok => Ok(()),
246 VfsResponse::Err(e) => Err(e),
247 _ => Err(VfsError::ParseError {
248 error: "unexpected response".to_string(),
249 path: self.path.clone(),
250 }),
251 }
252 }
253
254 pub fn metadata(&self) -> Result<FileMetadata, VfsError> {
256 let message = vfs_request(&self.path, VfsAction::Metadata)
257 .send_and_await_response(self.timeout)
258 .unwrap()
259 .map_err(|e| VfsError::SendError(e.kind))?;
260
261 match parse_response(message.body())? {
262 VfsResponse::Metadata(metadata) => Ok(metadata),
263 VfsResponse::Err(e) => Err(e),
264 _ => Err(VfsError::ParseError {
265 error: "unexpected response".to_string(),
266 path: self.path.clone(),
267 }),
268 }
269 }
270
271 pub fn sync_all(&self) -> Result<(), VfsError> {
273 let message = vfs_request(&self.path, VfsAction::SyncAll)
274 .send_and_await_response(self.timeout)
275 .unwrap()
276 .map_err(|e| VfsError::SendError(e.kind))?;
277
278 match parse_response(message.body())? {
279 VfsResponse::Ok => Ok(()),
280 VfsResponse::Err(e) => Err(e),
281 _ => Err(VfsError::ParseError {
282 error: "unexpected response".to_string(),
283 path: self.path.clone(),
284 }),
285 }
286 }
287}
288
289impl Drop for File {
290 fn drop(&mut self) {
291 vfs_request(&self.path, VfsAction::CloseFile)
292 .send()
293 .unwrap();
294 }
295}
296
297pub fn create_drive(
301 package_id: PackageId,
302 drive: &str,
303 timeout: Option<u64>,
304) -> Result<String, VfsError> {
305 let timeout = timeout.unwrap_or(5);
306 let path = format!("/{}/{}", package_id, drive);
307
308 let message = vfs_request(&path, VfsAction::CreateDrive)
309 .send_and_await_response(timeout)
310 .unwrap()
311 .map_err(|e| VfsError::SendError(e.kind))?;
312
313 match parse_response(message.body())? {
314 VfsResponse::Ok => Ok(path),
315 VfsResponse::Err(e) => Err(e),
316 _ => Err(VfsError::ParseError {
317 error: "unexpected response".to_string(),
318 path,
319 }),
320 }
321}
322
323pub fn open_file(path: &str, create: bool, timeout: Option<u64>) -> Result<File, VfsError> {
325 let timeout = timeout.unwrap_or(5);
326
327 let message = vfs_request(path, VfsAction::OpenFile { create })
328 .send_and_await_response(timeout)
329 .unwrap()
330 .map_err(|e| VfsError::SendError(e.kind))?;
331
332 match parse_response(message.body())? {
333 VfsResponse::Ok => Ok(File {
334 path: path.to_string(),
335 timeout,
336 }),
337 VfsResponse::Err(e) => Err(e),
338 _ => Err(VfsError::ParseError {
339 error: "unexpected response".to_string(),
340 path: path.to_string(),
341 }),
342 }
343}
344
345pub fn create_file(path: &str, timeout: Option<u64>) -> Result<File, VfsError> {
347 let timeout = timeout.unwrap_or(5);
348
349 let message = vfs_request(path, VfsAction::CreateFile)
350 .send_and_await_response(timeout)
351 .unwrap()
352 .map_err(|e| VfsError::SendError(e.kind))?;
353
354 match parse_response(message.body())? {
355 VfsResponse::Ok => Ok(File {
356 path: path.to_string(),
357 timeout,
358 }),
359 VfsResponse::Err(e) => Err(e),
360 _ => Err(VfsError::ParseError {
361 error: "unexpected response".to_string(),
362 path: path.to_string(),
363 }),
364 }
365}
366
367pub fn remove_file(path: &str, timeout: Option<u64>) -> Result<(), VfsError> {
369 let timeout = timeout.unwrap_or(5);
370
371 let message = vfs_request(path, VfsAction::RemoveFile)
372 .send_and_await_response(timeout)
373 .unwrap()
374 .map_err(|e| VfsError::SendError(e.kind))?;
375
376 match parse_response(message.body())? {
377 VfsResponse::Ok => Ok(()),
378 VfsResponse::Err(e) => Err(e.into()),
379 _ => Err(VfsError::ParseError {
380 error: "unexpected response".to_string(),
381 path: path.to_string(),
382 }),
383 }
384}