shared_bytes/
range_of_subset.rs1use crate::{SharedBytes, SharedStr};
2use std::{fmt::Debug, ops::Range};
3
4mod private {
5 pub trait Sealed {}
6}
7
8pub trait RangeOfSubset: private::Sealed {
9 fn range_of_subset(&self, subset: &Self) -> Range<usize>;
10}
11
12impl<T> private::Sealed for [T] where T: Debug {}
13impl<T> RangeOfSubset for [T]
14where
15 T: Debug,
16{
17 fn range_of_subset(&self, subset: &Self) -> Range<usize> {
18 self.as_ptr().range_of_subset(subset.as_ptr(), subset.len())
19 }
20}
21
22impl private::Sealed for str {}
23impl RangeOfSubset for str {
24 fn range_of_subset(&self, subset: &Self) -> Range<usize> {
25 self.as_ptr().range_of_subset(subset.as_ptr(), subset.len())
26 }
27}
28
29impl private::Sealed for SharedBytes {}
30impl RangeOfSubset for SharedBytes {
31 fn range_of_subset(&self, subset: &Self) -> Range<usize> {
32 self.range_of_subset(subset)
33 }
34}
35
36impl private::Sealed for SharedStr {}
37impl RangeOfSubset for SharedStr {
38 fn range_of_subset(&self, subset: &Self) -> Range<usize> {
39 self.range_of_subset(subset)
40 }
41}
42
43trait PtrRangeOfSubset {
44 fn range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Range<usize>;
45
46 fn try_range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Option<Range<usize>>;
47}
48
49impl<T> PtrRangeOfSubset for *const T
50where
51 T: Debug,
52{
53 fn range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Range<usize> {
54 self.try_range_of_subset(subset_ptr, subset_length)
55 .unwrap_or_else(|| {
56 panic!("slice at {subset_ptr:?} is not a subset of slice at {self:?}")
57 })
58 }
59
60 fn try_range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Option<Range<usize>> {
61 let start = (subset_ptr as usize).checked_sub(self as usize)?;
62 let end = start.checked_add(subset_length)?;
63 Some(start..end)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn shared_bytes_range_of_subset() {
73 let bytes = [0, 1, 2, 3, 4];
74 let shared = SharedBytes::from(bytes.to_vec());
75 let expected = 0..3;
76 let actual = shared.range_of_subset(&shared[expected.clone()]);
77 assert_eq!(actual, expected);
78 }
79}