rust-index: check that the entry bytes are the same in both indexes
This is a temporary measure to show that both the Rust and C indexes are
kept in sync.
Comes with some related documentation precisions.
For comparison of error cases, see `index_entry_binary()` in `revlog.c`.
--- a/rust/hg-core/src/revlog/index.rs Sat Sep 30 16:15:56 2023 +0200
+++ b/rust/hg-core/src/revlog/index.rs Thu Nov 02 11:16:13 2023 +0100
@@ -366,8 +366,11 @@
self.len() == 0
}
- /// Return the index entry corresponding to the given revision if it
- /// exists.
+ /// Return the index entry corresponding to the given revision or `None`
+ /// for [`NULL_REVISION`]
+ ///
+ /// The specified revision being of the checked type, it always exists
+ /// if it was validated by this index.
pub fn get_entry(&self, rev: Revision) -> Option<IndexEntry> {
if rev == NULL_REVISION {
return None;
@@ -379,6 +382,21 @@
})
}
+ /// Return the binary content of the index entry for the given revision
+ ///
+ /// See [get_entry()](`Self::get_entry()`) for cases when `None` is
+ /// returned.
+ pub fn entry_binary(&self, rev: Revision) -> Option<&[u8]> {
+ self.get_entry(rev).map(|e| {
+ let bytes = e.as_bytes();
+ if rev.0 == 0 {
+ &bytes[4..]
+ } else {
+ bytes
+ }
+ })
+ }
+
fn get_entry_inline(
&self,
rev: Revision,
@@ -543,6 +561,10 @@
pub fn hash(&self) -> &'a Node {
(&self.bytes[32..52]).try_into().unwrap()
}
+
+ pub fn as_bytes(&self) -> &'a [u8] {
+ self.bytes
+ }
}
#[cfg(test)]
--- a/rust/hg-core/src/revlog/mod.rs Sat Sep 30 16:15:56 2023 +0200
+++ b/rust/hg-core/src/revlog/mod.rs Thu Nov 02 11:16:13 2023 +0100
@@ -148,7 +148,9 @@
fn node(&self, rev: Revision) -> Option<&Node>;
/// Return a [`Revision`] if `rev` is a valid revision number for this
- /// index
+ /// index.
+ ///
+ /// [`NULL_REVISION`] is considered to be valid.
fn check_revision(&self, rev: UncheckedRevision) -> Option<Revision> {
let rev = rev.0;
--- a/rust/hg-cpython/src/revlog.rs Sat Sep 30 16:15:56 2023 +0200
+++ b/rust/hg-cpython/src/revlog.rs Thu Nov 02 11:16:13 2023 +0100
@@ -211,7 +211,16 @@
/// return the raw binary string representing a revision
def entry_binary(&self, *args, **kw) -> PyResult<PyObject> {
- self.call_cindex(py, "entry_binary", args, kw)
+ let rindex = self.index(py).borrow();
+ let rev = UncheckedRevision(args.get_item(py, 0).extract(py)?);
+ let rust_bytes = rindex.check_revision(rev).and_then(
+ |r| rindex.entry_binary(r))
+ .ok_or_else(|| rev_not_in_index(py, rev))?;
+ let rust_res = PyBytes::new(py, rust_bytes).into_object();
+
+ let c_res = self.call_cindex(py, "entry_binary", args, kw)?;
+ assert_py_eq(py, "entry_binary", &rust_res, &c_res)?;
+ Ok(rust_res)
}
/// return a binary packed version of the header
@@ -615,7 +624,6 @@
)
}
-#[allow(dead_code)]
fn rev_not_in_index(py: Python, rev: UncheckedRevision) -> PyErr {
PyErr::new::<ValueError, _>(
py,