rust/hg-core/src/revlog/manifest.rs
changeset 45533 89ac95bd4993
child 45540 f2de24c2b1f6
equal deleted inserted replaced
45532:c2317b7624fd 45533:89ac95bd4993
       
     1 use crate::revlog::revlog::{Revlog, RevlogError};
       
     2 use crate::revlog::Revision;
       
     3 use crate::utils::hg_path::HgPath;
       
     4 use std::path::PathBuf;
       
     5 
       
     6 /// A specialized `Revlog` to work with `manifest` data format.
       
     7 pub struct Manifest {
       
     8     /// The generic `revlog` format.
       
     9     revlog: Revlog,
       
    10 }
       
    11 
       
    12 impl Manifest {
       
    13     /// Open the `manifest` of a repository given by its root.
       
    14     pub fn open(root: &PathBuf) -> Result<Self, RevlogError> {
       
    15         let index_file = root.join(".hg/store/00manifest.i");
       
    16         let revlog = Revlog::open(&index_file)?;
       
    17         Ok(Self { revlog })
       
    18     }
       
    19 
       
    20     /// Return the `ManifestEntry` of a given node id.
       
    21     pub fn get_node(&self, node: &[u8]) -> Result<ManifestEntry, RevlogError> {
       
    22         let rev = self.revlog.get_node_rev(node)?;
       
    23         self.get_rev(rev)
       
    24     }
       
    25 
       
    26     /// Return the `ManifestEntry` of a given node revision.
       
    27     pub fn get_rev(
       
    28         &self,
       
    29         rev: Revision,
       
    30     ) -> Result<ManifestEntry, RevlogError> {
       
    31         let bytes = self.revlog.get_rev_data(rev)?;
       
    32         Ok(ManifestEntry { bytes })
       
    33     }
       
    34 }
       
    35 
       
    36 /// `Manifest` entry which knows how to interpret the `manifest` data bytes.
       
    37 #[derive(Debug)]
       
    38 pub struct ManifestEntry {
       
    39     bytes: Vec<u8>,
       
    40 }
       
    41 
       
    42 impl ManifestEntry {
       
    43     /// Return an iterator over the lines of the entry.
       
    44     pub fn lines(&self) -> impl Iterator<Item = &[u8]> {
       
    45         self.bytes
       
    46             .split(|b| b == &b'\n')
       
    47             .filter(|line| !line.is_empty())
       
    48     }
       
    49 
       
    50     /// Return an iterator over the files of the entry.
       
    51     pub fn files(&self) -> impl Iterator<Item = &HgPath> {
       
    52         self.lines().filter(|line| !line.is_empty()).map(|line| {
       
    53             let pos = line
       
    54                 .iter()
       
    55                 .position(|x| x == &b'\0')
       
    56                 .expect("manifest line should contain \\0");
       
    57             HgPath::new(&line[..pos])
       
    58         })
       
    59     }
       
    60 }