D7982: rust-utils: introduce `subslice_index` function

Alphare (Raphaël Gomès) phabricator at mercurial-scm.org
Fri Jan 24 10:12:48 UTC 2020


Alphare created this revision.
Herald added subscribers: mercurial-devel, kevincox.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  I implemented it for something that did not turn out to need it, maybe it'll be
  useful?

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7982

AFFECTED FILES
  rust/hg-core/src/utils.rs

CHANGE DETAILS

diff --git a/rust/hg-core/src/utils.rs b/rust/hg-core/src/utils.rs
--- a/rust/hg-core/src/utils.rs
+++ b/rust/hg-core/src/utils.rs
@@ -61,6 +61,36 @@
     }
 }
 
+/// Find the offset of the subslice relative to the original collection
+///
+/// This function panics for zero-sized types.
+/// # Examples:
+///
+/// ```
+/// use crate::hg::utils::subslice_offset;
+/// let mut line = b"Subslice me!".to_vec();
+/// assert_eq!(subslice_offset(&line, &line[8..]), Some(8));
+///
+/// assert_eq!(subslice_offset(&line, b"hahaha"), None);
+///
+/// // Empty array
+/// let v: [u8; 0] = [];
+/// assert_eq!(subslice_offset(&v, &v), Some(0));
+/// assert_eq!(subslice_offset(&v, b"hehe"), None);
+/// ```
+pub fn subslice_offset<T: Sized>(outer: &[T], inner: &[T]) -> Option<usize> {
+    let pointee_size = std::mem::size_of::<T>();
+    assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+    let outer_start = outer.as_ptr() as usize;
+    let inner = inner.as_ptr() as usize;
+    if inner < outer_start || inner > outer_start.wrapping_add(outer.len()) {
+        None
+    } else {
+        Some(inner.wrapping_sub(outer_start))
+    }
+}
+
 pub trait SliceExt {
     fn trim_end(&self) -> &Self;
     fn trim_start(&self) -> &Self;



To: Alphare, #hg-reviewers
Cc: kevincox, mercurial-devel


More information about the Mercurial-devel mailing list