shared_bytes/
range_of_subset.rs

1use 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}