diff rust/hg-core/src/revlog/index.rs @ 50988:1928b770e3e7

rust: use the new `UncheckedRevision` everywhere applicable This step converts all revisions that shouldn't be considered "valid" in any context to `UncheckedRevison`, allowing `Revision` to be changed for a stronger type in a later changeset. Note that the conversion from unchecked to checked is manual and requires at least some thought from the programmer, although directly using `Revision` is still possible. A later changeset will make this mistake harder to make.
author Rapha?l Gom?s <rgomes@octobus.net>
date Thu, 10 Aug 2023 11:00:34 +0200
parents e98fd81bb151
children 27e773aa607d
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/index.rs	Mon Sep 11 11:52:33 2023 +0200
+++ b/rust/hg-core/src/revlog/index.rs	Thu Aug 10 11:00:34 2023 +0200
@@ -1,3 +1,4 @@
+use std::fmt::Debug;
 use std::ops::Deref;
 
 use byteorder::{BigEndian, ByteOrder};
@@ -5,6 +6,7 @@
 use crate::errors::HgError;
 use crate::revlog::node::Node;
 use crate::revlog::{Revision, NULL_REVISION};
+use crate::UncheckedRevision;
 
 pub const INDEX_ENTRY_SIZE: usize = 64;
 
@@ -86,6 +88,15 @@
     uses_generaldelta: bool,
 }
 
+impl Debug for Index {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("Index")
+            .field("offsets", &self.offsets)
+            .field("uses_generaldelta", &self.uses_generaldelta)
+            .finish()
+    }
+}
+
 impl Index {
     /// Create an index from bytes.
     /// Calculate the start of each entry when is_inline is true.
@@ -175,36 +186,32 @@
         if rev == NULL_REVISION {
             return None;
         }
-        if let Some(offsets) = &self.offsets {
+        Some(if let Some(offsets) = &self.offsets {
             self.get_entry_inline(rev, offsets)
         } else {
             self.get_entry_separated(rev)
-        }
+        })
     }
 
     fn get_entry_inline(
         &self,
         rev: Revision,
         offsets: &[usize],
-    ) -> Option<IndexEntry> {
-        let start = *offsets.get(rev as usize)?;
-        let end = start.checked_add(INDEX_ENTRY_SIZE)?;
+    ) -> IndexEntry {
+        let start = offsets[rev as usize];
+        let end = start + INDEX_ENTRY_SIZE;
         let bytes = &self.bytes[start..end];
 
         // See IndexEntry for an explanation of this override.
         let offset_override = Some(end);
 
-        Some(IndexEntry {
+        IndexEntry {
             bytes,
             offset_override,
-        })
+        }
     }
 
-    fn get_entry_separated(&self, rev: Revision) -> Option<IndexEntry> {
-        let max_rev = self.bytes.len() / INDEX_ENTRY_SIZE;
-        if rev as usize >= max_rev {
-            return None;
-        }
+    fn get_entry_separated(&self, rev: Revision) -> IndexEntry {
         let start = rev as usize * INDEX_ENTRY_SIZE;
         let end = start + INDEX_ENTRY_SIZE;
         let bytes = &self.bytes[start..end];
@@ -213,10 +220,10 @@
         // for the index's metadata (saving space because it is always 0)
         let offset_override = if rev == 0 { Some(0) } else { None };
 
-        Some(IndexEntry {
+        IndexEntry {
             bytes,
             offset_override,
-        })
+        }
     }
 }
 
@@ -273,23 +280,23 @@
     }
 
     /// Return the revision upon which the data has been derived.
-    pub fn base_revision_or_base_of_delta_chain(&self) -> Revision {
+    pub fn base_revision_or_base_of_delta_chain(&self) -> UncheckedRevision {
         // TODO Maybe return an Option when base_revision == rev?
         //      Requires to add rev to IndexEntry
 
-        BigEndian::read_i32(&self.bytes[16..])
+        BigEndian::read_i32(&self.bytes[16..]).into()
     }
 
-    pub fn link_revision(&self) -> Revision {
-        BigEndian::read_i32(&self.bytes[20..])
+    pub fn link_revision(&self) -> UncheckedRevision {
+        BigEndian::read_i32(&self.bytes[20..]).into()
     }
 
-    pub fn p1(&self) -> Revision {
-        BigEndian::read_i32(&self.bytes[24..])
+    pub fn p1(&self) -> UncheckedRevision {
+        BigEndian::read_i32(&self.bytes[24..]).into()
     }
 
-    pub fn p2(&self) -> Revision {
-        BigEndian::read_i32(&self.bytes[28..])
+    pub fn p2(&self) -> UncheckedRevision {
+        BigEndian::read_i32(&self.bytes[28..]).into()
     }
 
     /// Return the hash of revision's full text.
@@ -547,7 +554,7 @@
             offset_override: None,
         };
 
-        assert_eq!(entry.base_revision_or_base_of_delta_chain(), 1)
+        assert_eq!(entry.base_revision_or_base_of_delta_chain(), 1.into())
     }
 
     #[test]
@@ -559,7 +566,7 @@
             offset_override: None,
         };
 
-        assert_eq!(entry.link_revision(), 123);
+        assert_eq!(entry.link_revision(), 123.into());
     }
 
     #[test]
@@ -571,7 +578,7 @@
             offset_override: None,
         };
 
-        assert_eq!(entry.p1(), 123);
+        assert_eq!(entry.p1(), 123.into());
     }
 
     #[test]
@@ -583,7 +590,7 @@
             offset_override: None,
         };
 
-        assert_eq!(entry.p2(), 123);
+        assert_eq!(entry.p2(), 123.into());
     }
 
     #[test]