1#[doc(hidden)]
33pub mod helpers;
34
35use crate::*;
36use std::path::{Path, PathBuf};
37use vfsi_core::internal::ManyResults;
38
39pub trait HandleBackend {
43 fn vstatfs_impl(&mut self, files: &[VfFile]) -> VfResult<Vec<FilesystemStats>> {
44 if files.is_empty() {
45 Ok(Vec::new())
46 } else {
47 Err(VfError::unsupported(0))
48 }
49 }
50
51 fn close_deferred(&mut self, file: &VfFile) -> VfResult<()> {
52 self.close_impl(file)
53 }
54
55 fn take_notifications(&mut self) -> Vec<Box<dyn FnOnce() + Send>> {
56 Vec::new()
57 }
58
59 fn capabilities(&self) -> Capabilities {
60 Capabilities::empty()
61 }
62
63 fn abs_path(&self, path: &Path) -> PathBuf {
64 path.to_path_buf()
65 }
66
67 fn open_path_impl(
68 &mut self,
69 _base: VfPathBase,
70 _pathname: &Path,
71 _flags: i32,
72 _mode: u32,
73 ) -> VfResult<VfFile> {
74 Err(VfError::unsupported(0))
75 }
76
77 fn vfsync_impl(&mut self, files: &[VfFile], mode: vfsi_core::api::SyncMode) -> VfRes {
80 for (index, file) in files.iter().enumerate() {
81 match mode {
82 vfsi_core::api::SyncMode::Data => self.sync_data(file),
83 vfsi_core::api::SyncMode::All => self.sync_all(file),
84 }
85 .map_err(|error| error.map_index(|_| index))?;
86 }
87 Ok(())
88 }
89
90 fn sync_data(&mut self, tcf: &VfFile) -> VfResult<()>;
91
92 fn sync_all(&mut self, tcf: &VfFile) -> VfResult<()> {
93 self.sync_data(tcf)
94 }
95
96 fn chdir(&mut self, _path: &Path) -> VfResult<()> {
97 Err(VfError::unsupported(0))
98 }
99
100 fn getcwd(&self) -> PathBuf {
101 PathBuf::from("/")
102 }
103
104 fn seek_raw_impl(&mut self, _tcf: &VfFile, _offset: i64, _whence: SeekFrom) -> VfResult<i64> {
105 Err(VfError::unsupported(0))
106 }
107
108 fn vf_path(&self, file: &VfFile) -> VfResult<PathBuf> {
109 crate::backend::helpers::vf_path_default(self, file)
110 }
111
112 fn open_raw_impl(&mut self, pathname: &Path, flags: i32, mode: u32) -> VfResult<VfFile> {
113 crate::backend::helpers::open_raw_impl_default(self, pathname, flags, mode)
114 }
115
116 fn read_raw_impl(&mut self, file: &VfFile, offset: u64, length: usize) -> VfResult<Vec<u8>> {
117 crate::backend::helpers::read_raw_impl_default(self, file, offset, length)
118 }
119
120 fn write_raw_impl(&mut self, file: &VfFile, offset: u64, data: &[u8]) -> VfResult<usize> {
121 crate::backend::helpers::write_raw_impl_default(self, file, offset, data)
122 }
123
124 fn read_file_impl(&mut self, file: &VfFile, max_bytes: usize) -> VfResult<Vec<u8>> {
125 crate::backend::helpers::read_file_impl_default(self, file, max_bytes)
126 }
127
128 fn open_impl(&mut self, request: &OpenOp) -> VfResult<VfFile>;
129
130 fn close_impl(&mut self, file: &VfFile) -> VfResult<()>;
131
132 fn read_impl(&mut self, request: &ReadOp) -> VfResult<ReadResult>;
133
134 fn read_into_impl(&mut self, request: &ReadOp, buffer: &mut [u8]) -> VfResult<ReadIntoResult> {
135 crate::backend::helpers::read_into_impl_default(self, request, buffer)
136 }
137
138 fn write_impl(&mut self, request: WriteOp<&VfFile, &[u8]>) -> VfResult<WriteResult>;
139
140 fn seek_impl(&mut self, file: &VfFile, position: std::io::SeekFrom) -> VfResult<u64>;
141
142 fn metadata_impl(
145 &mut self,
146 target: Target<'_, VfFile>,
147 options: vfsi_core::api::AttrsOptions,
148 ) -> VfResult<VfAttrs>;
149
150 fn set_attributes_impl(&mut self, update: &SetAttrsOp<Target<'_, VfFile>>) -> VfResult<()>;
153
154 fn vsetattrs_impl(&mut self, updates: &[SetAttrsOp<Target<'_, VfFile>>]) -> VfResult<()> {
158 crate::backend::helpers::vsetattrs_impl_default(self, updates)
159 }
160}
161
162pub trait VectorBackend: HandleBackend {
173 fn vread_impl(&mut self, reads: &[ReadOp]) -> VfResult<Vec<ReadResult>>;
175
176 fn vread_into_impl(
177 &mut self,
178 reads: &[ReadOp],
179 buffers: &mut [&mut [u8]],
180 ) -> VfResult<Vec<ReadIntoResult>> {
181 crate::backend::helpers::vread_into_impl_default(self, reads, buffers)
182 }
183 fn vwrite_impl(&mut self, writes: &[WriteOp<&VfFile, &[u8]>]) -> VfResult<Vec<WriteResult>> {
186 let _ = writes;
187 Err(VfError::unsupported(0))
188 }
189
190 #[doc(hidden)]
193 fn vopen_outcomes_impl(
194 &mut self,
195 paths: &[&Path],
196 flags: &[i32],
197 modes: &[u32],
198 ) -> VfResult<ManyResults<VfFile>> {
199 crate::backend::helpers::vopen_outcomes_impl_default(self, paths, flags, modes)
200 }
201
202 fn before_open_cleanup(&mut self, _index: usize, _file: &VfFile) -> VfResult<()> {
203 crate::backend::helpers::before_open_cleanup_default(self, _index, _file)
204 }
205
206 fn vopen_raw_impl(
207 &mut self,
208 paths: &[&Path],
209 flags: &[i32],
210 modes: &[u32],
211 ) -> VfResult<Vec<VfFile>> {
212 crate::backend::helpers::vopen_raw_impl_default(self, paths, flags, modes)
213 }
214
215 fn vopen_raw_simple_impl(
216 &mut self,
217 paths: &[&Path],
218 flags: i32,
219 mode: u32,
220 ) -> VfResult<Vec<VfFile>> {
221 crate::backend::helpers::vopen_raw_simple_impl_default(self, paths, flags, mode)
222 }
223
224 fn vclose_impl(&mut self, files: &[VfFile]) -> VfRes {
225 crate::backend::helpers::vclose_impl_default(self, files)
226 }
227
228 fn vopen_impl(&mut self, requests: &[OpenOp]) -> VfResult<Vec<VfFile>> {
231 crate::backend::helpers::vopen_typed_default(self, requests)
232 }
233
234 fn vgetattrs_impl(&mut self, attrs: &mut [VfAttrs]) -> VfRes {
236 let _ = (attrs,);
237 Err(VfError::unsupported(0))
238 }
239
240 fn vgetattrs_nofollow_impl(&mut self, attrs: &mut [VfAttrs]) -> VfRes {
241 let _ = (attrs,);
242 Err(VfError::unsupported(0))
243 }
244
245 fn vsetattrs_raw_impl(&mut self, attrs: &[VfAttrs]) -> VfRes {
246 let _ = (attrs,);
247 Err(VfError::unsupported(0))
248 }
249
250 fn vsetattrs_raw_nofollow_impl(&mut self, attrs: &[VfAttrs]) -> VfRes {
251 let _ = (attrs,);
252 Err(VfError::unsupported(0))
253 }
254
255 fn stat_impl(&mut self, path: &Path) -> VfResult<VfAttrs> {
256 crate::backend::helpers::stat_impl_default(self, path)
257 }
258
259 fn lstat_impl(&mut self, path: &Path) -> VfResult<VfAttrs> {
260 crate::backend::helpers::lstat_impl_default(self, path)
261 }
262
263 fn fstat_impl(&mut self, tcf: &VfFile) -> VfResult<VfAttrs> {
264 crate::backend::helpers::fstat_impl_default(self, tcf)
265 }
266
267 fn exists_impl(&mut self, path: &Path) -> VfResult<bool> {
268 crate::backend::helpers::exists_impl_default(self, path)
269 }
270
271 fn file_type_impl(&mut self, path: &Path) -> VfResult<VfType> {
272 crate::backend::helpers::file_type_impl_default(self, path)
273 }
274
275 fn metadata_path_impl(&mut self, path: &std::path::Path, follow: bool) -> VfResult<Attrs> {
276 crate::backend::helpers::native_metadata_path_impl_default(self, path, follow)
277 }
278
279 fn set_metadata_path_impl(&mut self, op: &SetAttrsOp<&std::path::Path>) -> VfResult<()> {
280 crate::backend::helpers::native_set_metadata_path_impl_default(self, op)
281 }
282
283 fn listdir_impl(
285 &mut self,
286 dir: &Path,
287 masks: AttrMask,
288 max_count: usize,
289 recursive: bool,
290 ) -> VfResult<Vec<VfAttrs>> {
291 let _ = (dir, masks, max_count, recursive);
292 Err(VfError::unsupported(0))
293 }
294
295 fn listdir_page_impl(
299 &mut self,
300 dir: &Path,
301 masks: AttrMask,
302 cursor: Option<DirPageCursor>,
303 page_size: usize,
304 max_entries: usize,
305 follow_symlinks: bool,
306 ) -> VfResult<(Vec<VfAttrs>, Option<DirPageCursor>)> {
307 crate::backend::helpers::listdir_page_impl_default(
308 self,
309 dir,
310 masks,
311 cursor,
312 page_size,
313 max_entries,
314 follow_symlinks,
315 )
316 }
317
318 fn directory_page_batch_size(&self) -> usize {
319 crate::backend::helpers::directory_page_batch_size_default(self)
320 }
321
322 fn vlistdir_pages_impl(
323 &mut self,
324 dirs: &[&Path],
325 masks: AttrMask,
326 cursors: Vec<Option<DirPageCursor>>,
327 page_size: usize,
328 max_entries: usize,
329 follow_symlinks: bool,
330 ) -> VfResult<Vec<BackendDirectoryPage>> {
331 crate::backend::helpers::vlistdir_pages_impl_default(
332 self,
333 dirs,
334 masks,
335 cursors,
336 page_size,
337 max_entries,
338 follow_symlinks,
339 )
340 }
341
342 fn create_dir_impl(&mut self, path: &std::path::Path, mode: u32) -> VfResult<()> {
343 crate::backend::helpers::native_create_dir_impl_default(self, path, mode)
344 }
345
346 fn read_dir_impl(
347 &mut self,
348 path: &std::path::Path,
349 options: ListDirOptions,
350 ) -> VfResult<Vec<DirEntry>> {
351 crate::backend::helpers::native_read_dir_impl_default(self, path, options)
352 }
353
354 fn read_dir_page_impl(
356 &mut self,
357 path: &std::path::Path,
358 cursor: Option<DirPageCursor>,
359 page_size: usize,
360 max_entries: usize,
361 ) -> VfResult<(Vec<DirEntry>, Option<DirPageCursor>)> {
362 crate::backend::helpers::native_read_dir_page_impl_default(
363 self,
364 path,
365 cursor,
366 page_size,
367 max_entries,
368 )
369 }
370
371 fn read_dir_page_with_fields_impl(
375 &mut self,
376 path: &std::path::Path,
377 fields: AttrMask,
378 cursor: Option<DirPageCursor>,
379 page_size: usize,
380 max_entries: usize,
381 ) -> VfResult<(Vec<DirEntry>, Option<DirPageCursor>)> {
382 crate::backend::helpers::native_read_dir_page_with_fields_impl_default(
383 self,
384 path,
385 fields,
386 cursor,
387 page_size,
388 max_entries,
389 )
390 }
391
392 fn walk_impl(
394 &mut self,
395 root: &Path,
396 masks: AttrMask,
397 sort: &mut dyn FnMut(&Path, &mut Vec<VfAttrs>),
398 ) -> VfResult<Vec<WalkEntry>> {
399 crate::backend::helpers::walk_impl_default(self, root, masks, sort)
400 }
401
402 fn walk_with_options_impl(
403 &mut self,
404 root: &Path,
405 masks: AttrMask,
406 options: ListDirOptions,
407 sort: &mut dyn FnMut(&Path, &mut Vec<VfAttrs>),
408 ) -> VfResult<Vec<WalkEntry>> {
409 crate::backend::helpers::walk_with_options_impl_default(self, root, masks, options, sort)
410 }
411
412 fn vlistdirs_impl(
413 &mut self,
414 dirs: &[&Path],
415 masks: AttrMask,
416 max_entries: usize,
417 recursive: bool,
418 cb: &mut dyn FnMut(&VfAttrs, &Path) -> bool,
419 ) -> VfRes {
420 crate::backend::helpers::vlistdirs_impl_default(
421 self,
422 dirs,
423 masks,
424 max_entries,
425 recursive,
426 cb,
427 )
428 }
429
430 fn visit_dir_impl(
431 &mut self,
432 dir: &Path,
433 masks: AttrMask,
434 max_entries: usize,
435 cb: &mut dyn FnMut(&VfAttrs) -> bool,
436 ) -> VfRes {
437 crate::backend::helpers::visit_dir_impl_default(self, dir, masks, max_entries, cb)
438 }
439
440 fn vrename_impl(&mut self, pairs: &[(VfFile, VfFile)]) -> VfRes {
442 let _ = (pairs,);
443 Err(VfError::unsupported(0))
444 }
445
446 fn vrename_with_options_impl(
448 &mut self,
449 pairs: &[(VfFile, VfFile)],
450 options: vfsi_core::api::RenameOptions,
451 ) -> VfRes {
452 match options {
453 vfsi_core::api::RenameOptions::Replace => self.vrename_impl(pairs),
454 vfsi_core::api::RenameOptions::NoReplace | vfsi_core::api::RenameOptions::Exchange
455 if pairs.is_empty() =>
456 {
457 Ok(())
458 }
459 vfsi_core::api::RenameOptions::NoReplace | vfsi_core::api::RenameOptions::Exchange => {
460 Err(VfError::client(0, vfsi_core::VF_ERR_UNSUPPORTED))
461 }
462 }
463 }
464
465 fn vremove_impl(&mut self, files: &[VfFile]) -> VfRes {
466 let _ = (files,);
467 Err(VfError::unsupported(0))
468 }
469
470 fn vmkdir_impl(&mut self, dirs: &[VfAttrs]) -> VfRes {
471 let _ = (dirs,);
472 Err(VfError::unsupported(0))
473 }
474
475 fn unlink_impl(&mut self, pathname: &Path) -> VfResult<()> {
476 crate::backend::helpers::unlink_impl_default(self, pathname)
477 }
478
479 fn vunlink_impl(&mut self, pathnames: &[&Path]) -> VfRes {
480 crate::backend::helpers::vunlink_impl_default(self, pathnames)
481 }
482
483 fn mkdir_raw_impl(&mut self, path: &Path, mode: u32) -> VfResult<()> {
484 crate::backend::helpers::mkdir_raw_impl_default(self, path, mode)
485 }
486
487 fn ensure_dir_impl(&mut self, dir: &Path, mode: u32) -> VfResult<()> {
488 crate::backend::helpers::ensure_dir_impl_default(self, dir, mode)
489 }
490
491 fn remove_impl(&mut self, path: &std::path::Path, recursive: bool) -> VfResult<()> {
492 crate::backend::helpers::native_remove_impl_default(self, path, recursive)
493 }
494
495 fn remove_dir_contents_impl(&mut self, path: &std::path::Path) -> VfResult<()> {
496 crate::backend::helpers::native_remove_dir_contents_impl_default(self, path)
497 }
498
499 fn rename_impl(&mut self, from: &std::path::Path, to: &std::path::Path) -> VfResult<()> {
500 crate::backend::helpers::native_rename_impl_default(self, from, to)
501 }
502
503 fn vsymlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
505 let _ = (oldpaths, newpaths);
506 Err(VfError::unsupported(0))
507 }
508
509 fn vreadlink_impl(&mut self, paths: &[&Path]) -> VfResult<Vec<Vec<u8>>> {
510 let _ = (paths,);
511 Err(VfError::unsupported(0))
512 }
513
514 fn vhardlink_impl(&mut self, oldpaths: &[&Path], newpaths: &[&Path]) -> VfRes {
515 let _ = (oldpaths, newpaths);
516 Err(VfError::unsupported(0))
517 }
518
519 fn symlink_raw_impl(&mut self, oldpath: &Path, newpath: &Path) -> VfResult<()> {
520 crate::backend::helpers::symlink_raw_impl_default(self, oldpath, newpath)
521 }
522
523 fn readlink_raw_impl(&mut self, path: &Path) -> VfResult<Vec<u8>> {
524 crate::backend::helpers::readlink_raw_impl_default(self, path)
525 }
526
527 fn symlink_impl(&mut self, target: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
528 crate::backend::helpers::native_symlink_impl_default(self, target, link)
529 }
530
531 fn hard_link_impl(&mut self, source: &std::path::Path, link: &std::path::Path) -> VfResult<()> {
532 crate::backend::helpers::native_hard_link_impl_default(self, source, link)
533 }
534
535 fn read_link_impl(&mut self, path: &std::path::Path) -> VfResult<std::path::PathBuf> {
536 crate::backend::helpers::native_read_link_impl_default(self, path)
537 }
538
539 fn vcopy_data_impl(&mut self, pairs: &[ExtentPair]) -> VfRes {
541 let _ = (pairs,);
542 Err(VfError::unsupported(0))
543 }
544
545 fn vcopy_impl(&mut self, pairs: &[ExtentPair], options: CopyOption) -> VfRes {
546 crate::backend::helpers::vcopy_impl_default(self, pairs, options)
547 }
548
549 fn copy_tree_impl(
550 &mut self,
551 src_dir: &Path,
552 dst: &Path,
553 symlinks: bool,
554 use_server_side_copy: bool,
555 ) -> VfRes {
556 let _ = (src_dir, dst, symlinks, use_server_side_copy);
557 Err(VfError::unsupported(0))
558 }
559
560 fn vread_all_impl(&mut self, files: &[VfFile]) -> VfResult<Vec<Vec<u8>>> {
562 crate::backend::helpers::vread_all_impl_default(self, files)
563 }
564
565 fn vread_all_with_options_impl(
566 &mut self,
567 files: &[VfFile],
568 options: ReadAllOptions,
569 ) -> VfResult<Vec<Vec<u8>>> {
570 crate::backend::helpers::vread_all_with_options_impl_default(self, files, options)
571 }
572
573 fn vstream_impl(
574 &mut self,
575 files: &[VfFile],
576 chunk_size: usize,
577 memory_limit: usize,
578 cb: &mut ReadStreamCallback<'_>,
579 ) -> VfRes {
580 crate::backend::helpers::vstream_impl_default(self, files, chunk_size, memory_limit, cb)
581 }
582
583 fn before_remove_type(&mut self, _index: usize) -> VfResult<()> {
585 crate::backend::helpers::before_remove_type_default(self, _index)
586 }
587
588 fn remove_paths_impl(&mut self, objs: &[&Path], recursive: bool) -> VfRes {
589 crate::backend::helpers::remove_paths_impl_default(self, objs, recursive)
590 }
591
592 fn remove_paths_with_options_impl(
593 &mut self,
594 objs: &[&Path],
595 recursive: bool,
596 options: RemoveOptions,
597 ) -> VfRes {
598 crate::backend::helpers::remove_paths_with_options_impl_default(
599 self, objs, recursive, options,
600 )
601 }
602
603 fn open_dir_impl(&mut self, path: &Path) -> VfResult<VfDir> {
604 crate::backend::helpers::open_dir_impl_default(self, path)
605 }
606
607 fn remove_dir_contents_handle_impl(&mut self, dir: &VfDir) -> VfRes {
608 crate::backend::helpers::remove_dir_contents_handle_impl_default(self, dir)
609 }
610
611 fn remove_dir_contents_handle_with_options_impl(
612 &mut self,
613 dir: &VfDir,
614 options: RemoveOptions,
615 ) -> VfRes {
616 crate::backend::helpers::remove_dir_contents_handle_with_options_impl_default(
617 self, dir, options,
618 )
619 }
620
621 fn close_dir_impl(&mut self, _dir: &VfDir) -> VfResult<()> {
622 crate::backend::helpers::close_dir_impl_default(self, _dir)
623 }
624
625 fn remove_dir_contents_path_impl(&mut self, dir: &Path) -> VfRes {
626 crate::backend::helpers::remove_dir_contents_path_impl_default(self, dir)
627 }
628
629 fn remove_dir_contents_path_with_options_impl(
630 &mut self,
631 dir: &Path,
632 options: RemoveOptions,
633 ) -> VfRes {
634 crate::backend::helpers::remove_dir_contents_path_with_options_impl_default(
635 self, dir, options,
636 )
637 }
638
639 fn ensure_empty_dir_impl(&mut self, dir: &Path) -> VfRes {
640 crate::backend::helpers::ensure_empty_dir_impl_default(self, dir)
641 }
642
643 fn vwrite_adb_impl(&mut self, patterns: &[Adb]) -> VfResult<Vec<usize>> {
645 let _ = (patterns,);
646 Err(VfError::unsupported(0))
647 }
648}
649pub(crate) fn metadata_mask() -> AttrMask {
650 AttrMask::MODE
651 | AttrMask::SIZE
652 | AttrMask::NLINK
653 | AttrMask::FILEID
654 | AttrMask::UID
655 | AttrMask::GID
656 | AttrMask::ATIME
657 | AttrMask::MTIME
658 | AttrMask::CTIME
659 | AttrMask::CHANGE
660}
661
662pub(crate) fn system_time_parts(time: std::time::SystemTime) -> VfResult<(i64, u32)> {
663 match time.duration_since(std::time::UNIX_EPOCH) {
664 Ok(duration) => Ok((
665 i64::try_from(duration.as_secs())
666 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?,
667 duration.subsec_nanos(),
668 )),
669 Err(error) => {
670 let duration = error.duration();
671 let seconds = i64::try_from(duration.as_secs())
672 .map_err(|_| VfError::client(0, libc::EOVERFLOW as u32))?;
673 if duration.subsec_nanos() == 0 {
674 Ok((-seconds, 0))
675 } else {
676 let seconds = seconds
677 .checked_add(1)
678 .ok_or_else(|| VfError::client(0, libc::EOVERFLOW as u32))?;
679 Ok((-seconds, 1_000_000_000 - duration.subsec_nanos()))
680 }
681 }
682 }
683}
684#[cfg(unix)]
685pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
686 use std::os::unix::ffi::OsStringExt;
687 std::ffi::OsString::from_vec(bytes).into()
688}
689#[cfg(not(unix))]
690pub(crate) fn bytes_to_path(bytes: Vec<u8>) -> PathBuf {
691 String::from_utf8_lossy(&bytes).into_owned().into()
692}
693pub(crate) fn translate_open_flags(requests: &[OpenOp]) -> VfResult<Vec<i32>> {
694 requests
695 .iter()
696 .enumerate()
697 .map(|(index, request)| {
698 vfsi_core::open_flags_to_libc(request.flags()).map_err(|error| error.with_index(index))
699 })
700 .collect()
701}