Mercurial > public > mercurial-scm > hg
diff rust/hg-core/src/revlog/filelog.rs @ 48237:027ebad952ac
rhg: internally, return a structured representation from hg cat
The purpose of this change is to make it possible to support limited templating in `hg cat`, so we could print separators between files etc.
The templating itself is not implemented yet, so this functionality is unused in `rhg cat`.
However, in our fork of hg we're implementing a slightly different command `hg jscat` which makes use of this.
So accepting this change will let us minimize the size of the patch we're maintaining on our side.
Differential Revision: https://phab.mercurial-scm.org/D11679
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Fri, 15 Oct 2021 14:05:20 +0100 |
parents | 87e3f878e65f |
children | e9faae0f445c |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/filelog.rs Thu Oct 14 19:02:08 2021 +0100 +++ b/rust/hg-core/src/revlog/filelog.rs Fri Oct 15 14:05:20 2021 +0100 @@ -7,7 +7,6 @@ use crate::utils::files::get_path_from_bytes; use crate::utils::hg_path::HgPath; use crate::utils::SliceExt; -use std::borrow::Cow; use std::path::PathBuf; /// A specialized `Revlog` to work with file data logs. @@ -40,7 +39,7 @@ &self, file_rev: Revision, ) -> Result<FilelogEntry, RevlogError> { - let data = self.revlog.get_rev_data(file_rev)?; + let data: Vec<u8> = self.revlog.get_rev_data(file_rev)?; Ok(FilelogEntry(data.into())) } } @@ -51,22 +50,32 @@ get_path_from_bytes(&encoded_bytes).into() } -pub struct FilelogEntry<'filelog>(Cow<'filelog, [u8]>); +pub struct FilelogEntry(Vec<u8>); -impl<'filelog> FilelogEntry<'filelog> { +impl FilelogEntry { /// Split into metadata and data - pub fn split(&self) -> Result<(Option<&[u8]>, &[u8]), HgError> { + /// Returns None if there is no metadata, so the entire entry is data. + fn split_metadata(&self) -> Result<Option<(&[u8], &[u8])>, HgError> { const DELIMITER: &[u8; 2] = &[b'\x01', b'\n']; if let Some(rest) = self.0.drop_prefix(DELIMITER) { if let Some((metadata, data)) = rest.split_2_by_slice(DELIMITER) { - Ok((Some(metadata), data)) + Ok(Some((metadata, data))) } else { Err(HgError::corrupted( "Missing metadata end delimiter in filelog entry", )) } } else { + Ok(None) + } + } + + /// Split into metadata and data + pub fn split(&self) -> Result<(Option<&[u8]>, &[u8]), HgError> { + if let Some((metadata, data)) = self.split_metadata()? { + Ok((Some(metadata), data)) + } else { Ok((None, &self.0)) } } @@ -76,4 +85,14 @@ let (_metadata, data) = self.split()?; Ok(data) } + + /// Consume the entry, and convert it into data, discarding any metadata, + /// if present. + pub fn into_data(self) -> Result<Vec<u8>, HgError> { + if let Some((_metadata, data)) = self.split_metadata()? { + Ok(data.to_owned()) + } else { + Ok(self.0) + } + } }