Mercurial > hg
changeset 47952:9cd35c8c6044
rust: Move VFS code to its own module
It was previously in the hg::repo module, but both repo code and vfs
will likely grow in the future.
Differential Revision: https://phab.mercurial-scm.org/D11394
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 06 Sep 2021 11:39:59 +0200 |
parents | cff41e168c25 |
children | 8f031a274cd6 |
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 |
diffstat | 5 files changed, 79 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/lib.rs Fri Sep 03 16:32:35 2021 +0200 +++ b/rust/hg-core/src/lib.rs Mon Sep 06 11:39:59 2021 +0200 @@ -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::{
--- a/rust/hg-core/src/logging.rs Fri Sep 03 16:32:35 2021 +0200 +++ b/rust/hg-core/src/logging.rs Mon Sep 06 11:39:59 2021 +0200 @@ -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
--- a/rust/hg-core/src/repo.rs Fri Sep 03 16:32:35 2021 +0200 +++ b/rust/hg-core/src/repo.rs Mon Sep 06 11:39:59 2021 +0200 @@ -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())) -}
--- a/rust/hg-core/src/requirements.rs Fri Sep 03 16:32:35 2021 +0200 +++ b/rust/hg-core/src/requirements.rs Mon Sep 06 11:39:59 2021 +0200 @@ -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> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hg-core/src/vfs.rs Mon Sep 06 11:39:59 2021 +0200 @@ -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())) +}