Mercurial > hg
changeset 51203:7434747343ab
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`.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Thu, 02 Nov 2023 11:16:13 +0100 |
parents | 16d477bb0078 |
children | 297fa956b6c4 |
files | rust/hg-core/src/revlog/index.rs rust/hg-core/src/revlog/mod.rs rust/hg-cpython/src/revlog.rs |
diffstat | 3 files changed, 37 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- 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,