Mercurial > hg
changeset 45532:c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
A facade to `Revlog` to provide a `changelog` specific interface.
Differential Revision: https://phab.mercurial-scm.org/D9010
author | Antoine Cezar <antoine.cezar@octobus.net> |
---|---|
date | Wed, 09 Sep 2020 16:25:23 +0200 |
parents | b0d6309ff50c |
children | 89ac95bd4993 |
files | rust/hg-core/src/revlog.rs rust/hg-core/src/revlog/changelog.rs |
diffstat | 2 files changed, 59 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog.rs Wed Sep 02 15:23:25 2020 +0200 +++ b/rust/hg-core/src/revlog.rs Wed Sep 09 16:25:23 2020 +0200 @@ -8,6 +8,7 @@ pub mod node; pub mod nodemap; pub use node::{Node, NodeError, NodePrefix, NodePrefixRef}; +pub mod changelog; pub mod index; pub mod patch; pub mod revlog;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hg-core/src/revlog/changelog.rs Wed Sep 09 16:25:23 2020 +0200 @@ -0,0 +1,58 @@ +use crate::revlog::revlog::{Revlog, RevlogError}; +use crate::revlog::Revision; +use std::path::PathBuf; + +/// A specialized `Revlog` to work with `changelog` data format. +pub struct Changelog { + /// The generic `revlog` format. + revlog: Revlog, +} + +impl Changelog { + /// Open the `changelog` of a repository given by its root. + pub fn open(root: &PathBuf) -> Result<Self, RevlogError> { + let index_file = root.join(".hg/store/00changelog.i"); + let revlog = Revlog::open(&index_file)?; + Ok(Self { revlog }) + } + + /// Return the `ChangelogEntry` a given node id. + pub fn get_node( + &self, + node: &[u8], + ) -> Result<ChangelogEntry, RevlogError> { + let rev = self.revlog.get_node_rev(node)?; + self.get_rev(rev) + } + + /// Return the `ChangelogEntry` of a given node revision. + pub fn get_rev( + &self, + rev: Revision, + ) -> Result<ChangelogEntry, RevlogError> { + let bytes = self.revlog.get_rev_data(rev)?; + Ok(ChangelogEntry { bytes }) + } +} + +/// `Changelog` entry which knows how to interpret the `changelog` data bytes. +#[derive(Debug)] +pub struct ChangelogEntry { + /// The data bytes of the `changelog` entry. + bytes: Vec<u8>, +} + +impl ChangelogEntry { + /// Return an iterator over the lines of the entry. + pub fn lines(&self) -> impl Iterator<Item = &[u8]> { + self.bytes + .split(|b| b == &b'\n') + .filter(|line| !line.is_empty()) + } + + /// Return the node id of the `manifest` referenced by this `changelog` + /// entry. + pub fn manifest_node(&self) -> Result<&[u8], RevlogError> { + self.lines().next().ok_or(RevlogError::Corrupted) + } +}