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