##// END OF EJS Templates
hg-core: add `Manifest` a specialized `Revlog`...
Antoine Cezar -
r46104:89ac95bd default
parent child Browse files
Show More
@@ -0,0 +1,60 b''
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 }
@@ -1,65 +1,66 b''
1 1 // Copyright 2018-2020 Georges Racinet <georges.racinet@octobus.net>
2 2 // and Mercurial contributors
3 3 //
4 4 // This software may be used and distributed according to the terms of the
5 5 // GNU General Public License version 2 or any later version.
6 6 //! Mercurial concepts for handling revision history
7 7
8 8 pub mod node;
9 9 pub mod nodemap;
10 10 pub use node::{Node, NodeError, NodePrefix, NodePrefixRef};
11 11 pub mod changelog;
12 12 pub mod index;
13 pub mod manifest;
13 14 pub mod patch;
14 15 pub mod revlog;
15 16
16 17 /// Mercurial revision numbers
17 18 ///
18 19 /// As noted in revlog.c, revision numbers are actually encoded in
19 20 /// 4 bytes, and are liberally converted to ints, whence the i32
20 21 pub type Revision = i32;
21 22
22 23 /// Marker expressing the absence of a parent
23 24 ///
24 25 /// Independently of the actual representation, `NULL_REVISION` is guaranteed
25 26 /// to be smaller than all existing revisions.
26 27 pub const NULL_REVISION: Revision = -1;
27 28
28 29 /// Same as `mercurial.node.wdirrev`
29 30 ///
30 31 /// This is also equal to `i32::max_value()`, but it's better to spell
31 32 /// it out explicitely, same as in `mercurial.node`
32 33 #[allow(clippy::unreadable_literal)]
33 34 pub const WORKING_DIRECTORY_REVISION: Revision = 0x7fffffff;
34 35
35 36 /// The simplest expression of what we need of Mercurial DAGs.
36 37 pub trait Graph {
37 38 /// Return the two parents of the given `Revision`.
38 39 ///
39 40 /// Each of the parents can be independently `NULL_REVISION`
40 41 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>;
41 42 }
42 43
43 44 #[derive(Clone, Debug, PartialEq)]
44 45 pub enum GraphError {
45 46 ParentOutOfRange(Revision),
46 47 WorkingDirectoryUnsupported,
47 48 }
48 49
49 50 /// The Mercurial Revlog Index
50 51 ///
51 52 /// This is currently limited to the minimal interface that is needed for
52 53 /// the [`nodemap`](nodemap/index.html) module
53 54 pub trait RevlogIndex {
54 55 /// Total number of Revisions referenced in this index
55 56 fn len(&self) -> usize;
56 57
57 58 fn is_empty(&self) -> bool {
58 59 self.len() == 0
59 60 }
60 61
61 62 /// Return a reference to the Node or `None` if rev is out of bounds
62 63 ///
63 64 /// `NULL_REVISION` is not considered to be out of bounds.
64 65 fn node(&self, rev: Revision) -> Option<&Node>;
65 66 }
General Comments 0
You need to be logged in to leave comments. Login now