516 } |
516 } |
517 |
517 |
518 /// Abstracts over the VFS to allow for different implementations of the |
518 /// Abstracts over the VFS to allow for different implementations of the |
519 /// filesystem layer (like passing one from Python). |
519 /// filesystem layer (like passing one from Python). |
520 pub trait Vfs: Sync + Send + DynClone { |
520 pub trait Vfs: Sync + Send + DynClone { |
521 // TODO make `open` readonly and make `open_read` an `open_write` |
521 /// Open a [`VfsFile::Normal`] for reading the file at `filename`, |
|
522 /// relative to this VFS's root. |
|
523 fn open(&self, filename: &Path) -> Result<VfsFile, HgError>; |
522 /// Open a [`VfsFile::Normal`] for writing and reading the file at |
524 /// Open a [`VfsFile::Normal`] for writing and reading the file at |
523 /// `filename`, relative to this VFS's root. |
525 /// `filename`, relative to this VFS's root. |
524 fn open(&self, filename: &Path) -> Result<VfsFile, HgError>; |
526 fn open_write(&self, filename: &Path) -> Result<VfsFile, HgError>; |
525 /// Open a [`VfsFile::Normal`] for reading the file at `filename`, |
|
526 /// relative to this VFS's root. |
|
527 fn open_read(&self, filename: &Path) -> Result<VfsFile, HgError>; |
|
528 /// Open a [`VfsFile::Normal`] for reading and writing the file at |
527 /// Open a [`VfsFile::Normal`] for reading and writing the file at |
529 /// `filename`, relative to this VFS's root. This file will be checked |
528 /// `filename`, relative to this VFS's root. This file will be checked |
530 /// for an ambiguous mtime on [`drop`]. See [`is_filetime_ambiguous`]. |
529 /// for an ambiguous mtime on [`drop`]. See [`is_filetime_ambiguous`]. |
531 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError>; |
530 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError>; |
532 /// Create a [`VfsFile::Normal`] for reading and writing the file at |
531 /// Create a [`VfsFile::Normal`] for reading and writing the file at |
578 |
577 |
579 /// These methods will need to be implemented once `rhg` (and other) non-Python |
578 /// These methods will need to be implemented once `rhg` (and other) non-Python |
580 /// users of `hg-core` start doing more on their own, like writing to files. |
579 /// users of `hg-core` start doing more on their own, like writing to files. |
581 impl Vfs for VfsImpl { |
580 impl Vfs for VfsImpl { |
582 fn open(&self, filename: &Path) -> Result<VfsFile, HgError> { |
581 fn open(&self, filename: &Path) -> Result<VfsFile, HgError> { |
|
582 // TODO auditpath |
|
583 let path = self.base.join(filename); |
|
584 Ok(VfsFile::normal( |
|
585 std::fs::File::open(&path).when_reading_file(&path)?, |
|
586 filename.to_owned(), |
|
587 )) |
|
588 } |
|
589 |
|
590 fn open_write(&self, filename: &Path) -> Result<VfsFile, HgError> { |
583 if self.readonly { |
591 if self.readonly { |
584 return Err(HgError::abort( |
592 return Err(HgError::abort( |
585 "write access in a readonly vfs", |
593 "write access in a readonly vfs", |
586 exit_codes::ABORT, |
594 exit_codes::ABORT, |
587 None, |
595 None, |
598 .write(true) |
606 .write(true) |
599 .read(true) |
607 .read(true) |
600 .open(&path) |
608 .open(&path) |
601 .when_writing_file(&path)?, |
609 .when_writing_file(&path)?, |
602 path.to_owned(), |
610 path.to_owned(), |
603 )) |
|
604 } |
|
605 |
|
606 fn open_read(&self, filename: &Path) -> Result<VfsFile, HgError> { |
|
607 // TODO auditpath |
|
608 let path = self.base.join(filename); |
|
609 Ok(VfsFile::normal( |
|
610 std::fs::File::open(&path).when_reading_file(&path)?, |
|
611 filename.to_owned(), |
|
612 )) |
611 )) |
613 } |
612 } |
614 |
613 |
615 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError> { |
614 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError> { |
616 if self.readonly { |
615 if self.readonly { |
841 } |
840 } |
842 |
841 |
843 impl Vfs for FnCacheVfs { |
842 impl Vfs for FnCacheVfs { |
844 fn open(&self, filename: &Path) -> Result<VfsFile, HgError> { |
843 fn open(&self, filename: &Path) -> Result<VfsFile, HgError> { |
845 let encoded = path_encode(&get_bytes_from_path(filename)); |
844 let encoded = path_encode(&get_bytes_from_path(filename)); |
|
845 let filename = get_path_from_bytes(&encoded); |
|
846 self.inner.open(filename) |
|
847 } |
|
848 |
|
849 fn open_write(&self, filename: &Path) -> Result<VfsFile, HgError> { |
|
850 let encoded = path_encode(&get_bytes_from_path(filename)); |
846 let encoded_path = get_path_from_bytes(&encoded); |
851 let encoded_path = get_path_from_bytes(&encoded); |
847 self.maybe_add_to_fncache(filename, encoded_path)?; |
852 self.maybe_add_to_fncache(filename, encoded_path)?; |
848 self.inner.open(encoded_path) |
853 self.inner.open_write(encoded_path) |
849 } |
|
850 |
|
851 fn open_read(&self, filename: &Path) -> Result<VfsFile, HgError> { |
|
852 let encoded = path_encode(&get_bytes_from_path(filename)); |
|
853 let filename = get_path_from_bytes(&encoded); |
|
854 self.inner.open_read(filename) |
|
855 } |
854 } |
856 |
855 |
857 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError> { |
856 fn open_check_ambig(&self, filename: &Path) -> Result<VfsFile, HgError> { |
858 let encoded = path_encode(&get_bytes_from_path(filename)); |
857 let encoded = path_encode(&get_bytes_from_path(filename)); |
859 let filename = get_path_from_bytes(&encoded); |
858 let filename = get_path_from_bytes(&encoded); |