changeset 50974:c950fdba7472

rust: add `UncheckedRevision` type This is the start of a series whose aim is to separate "checked" and "unchecked" revision numbers. A "checked" revision number is valid for a given index, allowing us to have faster algorithms that don't do redundant checks all the time and have a clearer view of the kinds of revisions we're working with.
author Raphaël Gomès <rgomes@octobus.net>
date Mon, 07 Aug 2023 12:53:43 +0200
parents fd6c748eb8a6
children 3aca98a35727
files rust/hg-core/src/revlog/mod.rs
diffstat 1 files changed, 20 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/mod.rs	Mon Aug 21 17:57:48 2023 -0400
+++ b/rust/hg-core/src/revlog/mod.rs	Mon Aug 07 12:53:43 2023 +0200
@@ -39,6 +39,16 @@
 /// 4 bytes, and are liberally converted to ints, whence the i32
 pub type Revision = i32;
 
+/// Unchecked Mercurial revision numbers.
+///
+/// Values of this type have no guarantee of being a valid revision number
+/// in any context. Use method `check_revision` to get a valid revision within
+/// the appropriate index object.
+///
+/// As noted in revlog.c, revision numbers are actually encoded in
+/// 4 bytes, and are liberally converted to ints, whence the i32
+pub type UncheckedRevision = i32;
+
 /// Marker expressing the absence of a parent
 ///
 /// Independently of the actual representation, `NULL_REVISION` is guaranteed
@@ -85,6 +95,16 @@
     ///
     /// `NULL_REVISION` is not considered to be out of bounds.
     fn node(&self, rev: Revision) -> Option<&Node>;
+
+    /// Return a [`Revision`] if `rev` is a valid revision number for this
+    /// index
+    fn check_revision(&self, rev: UncheckedRevision) -> Option<Revision> {
+        if rev == NULL_REVISION || (rev >= 0 && (rev as usize) < self.len()) {
+            Some(rev)
+        } else {
+            None
+        }
+    }
 }
 
 const REVISION_FLAG_CENSORED: u16 = 1 << 15;