##// END OF EJS Templates
copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()`...
copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()` Instead of filtering the relevant parent inside de ChangedFiles method, we now yield all copies information and let the caller do the filtering. Soon, the filtering will be replaced by dispatching. Differential Revision: https://phab.mercurial-scm.org/D9649

File last commit:

r47160:645ee722 default
r47320:a34cd9aa default
Show More
manifest.rs
76 lines | 2.3 KiB | application/rls-services+xml | RustLexer
use crate::repo::Repo;
use crate::revlog::revlog::{Revlog, RevlogError};
use crate::revlog::NodePrefix;
use crate::revlog::Revision;
use crate::utils::hg_path::HgPath;
/// A specialized `Revlog` to work with `manifest` data format.
pub struct Manifest {
/// The generic `revlog` format.
revlog: Revlog,
}
impl Manifest {
/// Open the `manifest` of a repository given by its root.
pub fn open(repo: &Repo) -> Result<Self, RevlogError> {
let revlog = Revlog::open(repo, "00manifest.i", None)?;
Ok(Self { revlog })
}
/// Return the `ManifestEntry` of a given node id.
pub fn get_node(
&self,
node: NodePrefix,
) -> Result<ManifestEntry, RevlogError> {
let rev = self.revlog.get_node_rev(node)?;
self.get_rev(rev)
}
/// Return the `ManifestEntry` of a given node revision.
pub fn get_rev(
&self,
rev: Revision,
) -> Result<ManifestEntry, RevlogError> {
let bytes = self.revlog.get_rev_data(rev)?;
Ok(ManifestEntry { bytes })
}
}
/// `Manifest` entry which knows how to interpret the `manifest` data bytes.
#[derive(Debug)]
pub struct ManifestEntry {
bytes: Vec<u8>,
}
impl ManifestEntry {
/// 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 an iterator over the files of the entry.
pub fn files(&self) -> impl Iterator<Item = &HgPath> {
self.lines().filter(|line| !line.is_empty()).map(|line| {
let pos = line
.iter()
.position(|x| x == &b'\0')
.expect("manifest line should contain \\0");
HgPath::new(&line[..pos])
})
}
/// Return an iterator over the files of the entry.
pub fn files_with_nodes(&self) -> impl Iterator<Item = (&HgPath, &[u8])> {
self.lines().filter(|line| !line.is_empty()).map(|line| {
let pos = line
.iter()
.position(|x| x == &b'\0')
.expect("manifest line should contain \\0");
let hash_start = pos + 1;
let hash_end = hash_start + 40;
(HgPath::new(&line[..pos]), &line[hash_start..hash_end])
})
}
}