shared_bytes 0.1.0-beta.4

Owned string and byte slices.
Documentation
use crate::{SharedBytes, SharedStr};
use std::{fmt::Debug, ops::Range};

mod private {
    pub trait Sealed {}
}

pub trait RangeOfSubset: private::Sealed {
    fn range_of_subset(&self, subset: &Self) -> Range<usize>;
}

impl<T> private::Sealed for [T] where T: Debug {}
impl<T> RangeOfSubset for [T]
where
    T: Debug,
{
    fn range_of_subset(&self, subset: &Self) -> Range<usize> {
        self.as_ptr().range_of_subset(subset.as_ptr(), subset.len())
    }
}

impl private::Sealed for str {}
impl RangeOfSubset for str {
    fn range_of_subset(&self, subset: &Self) -> Range<usize> {
        self.as_ptr().range_of_subset(subset.as_ptr(), subset.len())
    }
}

impl private::Sealed for SharedBytes {}
impl RangeOfSubset for SharedBytes {
    fn range_of_subset(&self, subset: &Self) -> Range<usize> {
        self.range_of_subset(subset)
    }
}

impl private::Sealed for SharedStr {}
impl RangeOfSubset for SharedStr {
    fn range_of_subset(&self, subset: &Self) -> Range<usize> {
        self.range_of_subset(subset)
    }
}

trait PtrRangeOfSubset {
    fn range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Range<usize>;

    fn try_range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Option<Range<usize>>;
}

impl<T> PtrRangeOfSubset for *const T
where
    T: Debug,
{
    fn range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Range<usize> {
        self.try_range_of_subset(subset_ptr, subset_length)
            .unwrap_or_else(|| {
                panic!("slice at {subset_ptr:?} is not a subset of slice at {self:?}")
            })
    }

    fn try_range_of_subset(self, subset_ptr: Self, subset_length: usize) -> Option<Range<usize>> {
        let start = (subset_ptr as usize).checked_sub(self as usize)?;
        let end = start.checked_add(subset_length)?;
        Some(start..end)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn shared_bytes_range_of_subset() {
        let bytes = [0, 1, 2, 3, 4];
        let shared = SharedBytes::from(bytes.to_vec());
        let expected = 0..3;
        let actual = shared.range_of_subset(&shared[expected.clone()]);
        assert_eq!(actual, expected);
    }
}