Mercurial > public > mercurial-scm > hg
view rust/hg-core/src/vfs.rs @ 47955:e834b79def74
rust: Switch to the memmap2-rs crate
https://github.com/RazrFalcon/memmap2-rs
This is a fork of the original memmap crate which appears to be unmaintained:
https://github.com/danburkert/memmap-rs/issues/90
This fork is the most popular according to https://crates.io/keywords/mmap
Differential Revision: https://phab.mercurial-scm.org/D11397
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 10 Sep 2021 09:53:09 +0200 |
parents | 9cd35c8c6044 |
children | 9d0e5629cfbf |
line wrap: on
line source
use crate::errors::{HgError, IoErrorContext, IoResultExt}; use memmap2::{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())) }