D11394: rust: Move VFS code to its own module
SimonSapin
phabricator at mercurial-scm.org
Fri Sep 10 15:11:59 UTC 2021
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
It was previously in the hg::repo module, but both repo code and vfs
will likely grow in the future.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D11394
AFFECTED FILES
rust/hg-core/src/lib.rs
rust/hg-core/src/logging.rs
rust/hg-core/src/repo.rs
rust/hg-core/src/requirements.rs
rust/hg-core/src/vfs.rs
CHANGE DETAILS
diff --git a/rust/hg-core/src/vfs.rs b/rust/hg-core/src/vfs.rs
new file mode 100644
--- /dev/null
+++ b/rust/hg-core/src/vfs.rs
@@ -0,0 +1,73 @@
+use crate::errors::{HgError, IoErrorContext, IoResultExt};
+use memmap::{Mmap, MmapOptions};
+use std::io::ErrorKind;
+use std::path::{Path, PathBuf};
+
+/// Filesystem access abstraction for the contents of a given "base" diretory
+#[derive(Clone, Copy)]
+pub struct Vfs<'a> {
+ pub(crate) base: &'a Path,
+}
+
+impl Vfs<'_> {
+ pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
+ self.base.join(relative_path)
+ }
+
+ pub fn read(
+ &self,
+ relative_path: impl AsRef<Path>,
+ ) -> Result<Vec<u8>, HgError> {
+ let path = self.join(relative_path);
+ std::fs::read(&path).when_reading_file(&path)
+ }
+
+ pub fn mmap_open(
+ &self,
+ relative_path: impl AsRef<Path>,
+ ) -> Result<Mmap, HgError> {
+ let path = self.base.join(relative_path);
+ let file = std::fs::File::open(&path).when_reading_file(&path)?;
+ // TODO: what are the safety requirements here?
+ let mmap = unsafe { MmapOptions::new().map(&file) }
+ .when_reading_file(&path)?;
+ Ok(mmap)
+ }
+
+ pub fn rename(
+ &self,
+ relative_from: impl AsRef<Path>,
+ relative_to: impl AsRef<Path>,
+ ) -> Result<(), HgError> {
+ let from = self.join(relative_from);
+ let to = self.join(relative_to);
+ std::fs::rename(&from, &to)
+ .with_context(|| IoErrorContext::RenamingFile { from, to })
+ }
+}
+
+fn fs_metadata(
+ path: impl AsRef<Path>,
+) -> Result<Option<std::fs::Metadata>, HgError> {
+ let path = path.as_ref();
+ match std::fs::metadata(path) {
+ Ok(meta) => Ok(Some(meta)),
+ Err(error) => match error.kind() {
+ // TODO: when we require a Rust version where `NotADirectory` is
+ // stable, invert this logic and return None for it and `NotFound`
+ // and propagate any other error.
+ ErrorKind::PermissionDenied => Err(error).with_context(|| {
+ IoErrorContext::ReadingMetadata(path.to_owned())
+ }),
+ _ => Ok(None),
+ },
+ }
+}
+
+pub(crate) fn is_dir(path: impl AsRef<Path>) -> Result<bool, HgError> {
+ Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_dir()))
+}
+
+pub(crate) fn is_file(path: impl AsRef<Path>) -> Result<bool, HgError> {
+ Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_file()))
+}
diff --git a/rust/hg-core/src/requirements.rs b/rust/hg-core/src/requirements.rs
--- a/rust/hg-core/src/requirements.rs
+++ b/rust/hg-core/src/requirements.rs
@@ -1,6 +1,7 @@
use crate::errors::{HgError, HgResultExt};
-use crate::repo::{Repo, Vfs};
+use crate::repo::Repo;
use crate::utils::join_display;
+use crate::vfs::Vfs;
use std::collections::HashSet;
fn parse(bytes: &[u8]) -> Result<HashSet<String>, HgError> {
diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs
--- a/rust/hg-core/src/repo.rs
+++ b/rust/hg-core/src/repo.rs
@@ -1,12 +1,11 @@
use crate::config::{Config, ConfigError, ConfigParseError};
-use crate::errors::{HgError, IoErrorContext, IoResultExt};
+use crate::errors::HgError;
use crate::exit_codes;
use crate::requirements;
use crate::utils::files::get_path_from_bytes;
use crate::utils::SliceExt;
-use memmap::{Mmap, MmapOptions};
+use crate::vfs::{is_dir, is_file, Vfs};
use std::collections::HashSet;
-use std::io::ErrorKind;
use std::path::{Path, PathBuf};
/// A repository on disk
@@ -38,12 +37,6 @@
}
}
-/// Filesystem access abstraction for the contents of a given "base" diretory
-#[derive(Clone, Copy)]
-pub struct Vfs<'a> {
- pub(crate) base: &'a Path,
-}
-
impl Repo {
/// tries to find nearest repository root in current working directory or
/// its ancestors
@@ -251,66 +244,3 @@
Ok(parents)
}
}
-
-impl Vfs<'_> {
- pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
- self.base.join(relative_path)
- }
-
- pub fn read(
- &self,
- relative_path: impl AsRef<Path>,
- ) -> Result<Vec<u8>, HgError> {
- let path = self.join(relative_path);
- std::fs::read(&path).when_reading_file(&path)
- }
-
- pub fn mmap_open(
- &self,
- relative_path: impl AsRef<Path>,
- ) -> Result<Mmap, HgError> {
- let path = self.base.join(relative_path);
- let file = std::fs::File::open(&path).when_reading_file(&path)?;
- // TODO: what are the safety requirements here?
- let mmap = unsafe { MmapOptions::new().map(&file) }
- .when_reading_file(&path)?;
- Ok(mmap)
- }
-
- pub fn rename(
- &self,
- relative_from: impl AsRef<Path>,
- relative_to: impl AsRef<Path>,
- ) -> Result<(), HgError> {
- let from = self.join(relative_from);
- let to = self.join(relative_to);
- std::fs::rename(&from, &to)
- .with_context(|| IoErrorContext::RenamingFile { from, to })
- }
-}
-
-fn fs_metadata(
- path: impl AsRef<Path>,
-) -> Result<Option<std::fs::Metadata>, HgError> {
- let path = path.as_ref();
- match std::fs::metadata(path) {
- Ok(meta) => Ok(Some(meta)),
- Err(error) => match error.kind() {
- // TODO: when we require a Rust version where `NotADirectory` is
- // stable, invert this logic and return None for it and `NotFound`
- // and propagate any other error.
- ErrorKind::PermissionDenied => Err(error).with_context(|| {
- IoErrorContext::ReadingMetadata(path.to_owned())
- }),
- _ => Ok(None),
- },
- }
-}
-
-fn is_dir(path: impl AsRef<Path>) -> Result<bool, HgError> {
- Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_dir()))
-}
-
-fn is_file(path: impl AsRef<Path>) -> Result<bool, HgError> {
- Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_file()))
-}
diff --git a/rust/hg-core/src/logging.rs b/rust/hg-core/src/logging.rs
--- a/rust/hg-core/src/logging.rs
+++ b/rust/hg-core/src/logging.rs
@@ -1,5 +1,5 @@
use crate::errors::{HgError, HgResultExt, IoErrorContext, IoResultExt};
-use crate::repo::Vfs;
+use crate::vfs::Vfs;
use std::io::Write;
/// An utility to append to a log file with the given name, and optionally
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -36,6 +36,7 @@
pub mod operations;
pub mod revset;
pub mod utils;
+pub mod vfs;
use crate::utils::hg_path::{HgPathBuf, HgPathError};
pub use filepatterns::{
To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list