Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/revlog/nodemap_docket.rs @ 46511:43d63979a75e
rust: use HgError in RevlogError and Vfs
Differential Revision: https://phab.mercurial-scm.org/D9897
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Wed, 27 Jan 2021 14:45:25 +0100 |
parents | 0800aa42bb4c |
children | 842f2372ced6 |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/nodemap_docket.rs Wed Jan 27 14:59:09 2021 +0100 +++ b/rust/hg-core/src/revlog/nodemap_docket.rs Wed Jan 27 14:45:25 2021 +0100 @@ -1,3 +1,4 @@ +use crate::errors::{HgError, HgResultExt}; use bytes_cast::{unaligned, BytesCast}; use memmap::Mmap; use std::path::{Path, PathBuf}; @@ -38,12 +39,12 @@ index_path: &Path, ) -> Result<Option<(Self, Mmap)>, RevlogError> { let docket_path = index_path.with_extension("n"); - let docket_bytes = match repo.store_vfs().read(&docket_path) { - Err(e) if e.kind() == std::io::ErrorKind::NotFound => { - return Ok(None) - } - Err(e) => return Err(RevlogError::IoError(e)), - Ok(bytes) => bytes, + let docket_bytes = if let Some(bytes) = + repo.store_vfs().read(&docket_path).io_not_found_as_none()? + { + bytes + } else { + return Ok(None); }; let input = if let Some((&ONDISK_VERSION, rest)) = @@ -54,36 +55,40 @@ return Ok(None); }; - let (header, rest) = DocketHeader::from_bytes(input)?; + /// Treat any error as a parse error + fn parse<T, E>(result: Result<T, E>) -> Result<T, RevlogError> { + result.map_err(|_| { + HgError::corrupted("nodemap docket parse error").into() + }) + } + + let (header, rest) = parse(DocketHeader::from_bytes(input))?; let uid_size = header.uid_size as usize; // TODO: do we care about overflow for 4 GB+ nodemap files on 32-bit // systems? let tip_node_size = header.tip_node_size.get() as usize; let data_length = header.data_length.get() as usize; - let (uid, rest) = u8::slice_from_bytes(rest, uid_size)?; - let (_tip_node, _rest) = u8::slice_from_bytes(rest, tip_node_size)?; - let uid = - std::str::from_utf8(uid).map_err(|_| RevlogError::Corrupted)?; + let (uid, rest) = parse(u8::slice_from_bytes(rest, uid_size))?; + let (_tip_node, _rest) = + parse(u8::slice_from_bytes(rest, tip_node_size))?; + let uid = parse(std::str::from_utf8(uid))?; let docket = NodeMapDocket { data_length }; let data_path = rawdata_path(&docket_path, uid); - // TODO: use `std::fs::read` here when the `persistent-nodemap.mmap` + // TODO: use `vfs.read()` here when the `persistent-nodemap.mmap` // config is false? - match repo.store_vfs().mmap_open(&data_path) { - Ok(mmap) => { - if mmap.len() >= data_length { - Ok(Some((docket, mmap))) - } else { - Err(RevlogError::Corrupted) - } + if let Some(mmap) = repo + .store_vfs() + .mmap_open(&data_path) + .io_not_found_as_none()? + { + if mmap.len() >= data_length { + Ok(Some((docket, mmap))) + } else { + Err(HgError::corrupted("persistent nodemap too short").into()) } - Err(error) => { - if error.kind() == std::io::ErrorKind::NotFound { - Ok(None) - } else { - Err(RevlogError::IoError(error)) - } - } + } else { + Ok(None) } } }