shared_bytes 0.1.0-beta.4

Owned string and byte slices.
Documentation
mod core;
mod length;
mod no_interior_mutability;
mod slice;
mod slice_owner;

use self::{
    core::OwnedSliceCore,
    length::Length,
    no_interior_mutability::NoInteriorMutability,
    slice::{Slice, TryIndexRange},
    slice_owner::SliceOwner,
};
use std::{
    fmt,
    ops::{Deref, Range},
    sync::Arc,
};

pub(crate) struct OwnedSlice<Owner, S: ?Sized>(OwnedSliceCore<Owner, S>);

impl<Owner, S> OwnedSlice<Owner, S>
where
    Owner: SliceOwner + NoInteriorMutability,
    Owner::Slice: Slice<S>,
    S: ?Sized,
{
    pub fn new(owner: Owner) -> Result<Self, Owner> {
        let identity_range = 0..owner.as_slice().length();
        Self::with_range(owner, identity_range)
    }

    pub fn with_range(owner: Owner, range: Range<usize>) -> Result<Self, Owner> {
        OwnedSliceCore::try_new(owner, range).map(Self)
    }

    pub fn try_map_output<O>(self) -> Result<OwnedSlice<Owner, O>, Self>
    where
        Owner: fmt::Debug,
        Owner::Slice: Slice<O>,
        O: ?Sized,
    {
        let range = self.0.slice_range();
        OwnedSlice::with_range(self.into_owner(), range.clone())
            .map_err(|owner| Self::with_range(owner, range).unwrap())
    }

    pub fn as_slice(&self) -> &S {
        self.0.as_slice()
    }

    pub fn slice_equals_owner(&self) -> bool {
        let range = self.0.slice_range();
        range.start == 0 && range.end == self.0.owner_length()
    }

    pub fn into_owner(self) -> Owner {
        self.0.into_owner()
    }

    #[must_use = "`try_slice_mut` may fail to mutate `self`"]
    pub fn try_slice_mut(&mut self, range: Range<usize>) -> Result<(), ()> {
        let old_range = self.0.slice_range();
        let new_start = range.start.checked_add(old_range.start).ok_or(())?;
        let new_end = range.end.checked_add(old_range.start).ok_or(())?;
        let new_range = new_start..new_end;
        if new_range.end <= old_range.end {
            self.0.set_slice_range(new_range)
        } else {
            Err(())
        }
    }
}

impl<Owner, S> OwnedSlice<Arc<Owner>, S>
where
    Owner: SliceOwner + NoInteriorMutability,
    Owner::Slice: Slice<S>,
    S: ?Sized,
{
    pub fn into_unwrapped<T, TFromOwner, TFromSlice>(
        self,
        t_from_owner: TFromOwner,
        t_from_slice: TFromSlice,
    ) -> T
    where
        TFromOwner: FnOnce(Owner) -> T,
        TFromSlice: FnOnce(&S) -> T,
    {
        let range = self.0.slice_range();
        if self.slice_equals_owner() {
            match Arc::try_unwrap(self.into_owner()) {
                Ok(owner) => t_from_owner(owner),
                Err(arc) => {
                    let slice = arc.as_slice().index(range);
                    t_from_slice(slice)
                }
            }
        } else {
            t_from_slice(self.as_slice())
        }
    }
}

impl<Owner, S> Clone for OwnedSlice<Owner, S>
where
    Owner: Clone,
    S: ?Sized,
{
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

impl<Owner, S> Deref for OwnedSlice<Owner, S>
where
    Owner: SliceOwner + NoInteriorMutability,
    Owner::Slice: Slice<S>,
    S: ?Sized,
{
    type Target = S;

    fn deref(&self) -> &Self::Target {
        self.0.as_slice()
    }
}

impl<Owner, S> fmt::Debug for OwnedSlice<Owner, S>
where
    Owner: SliceOwner + NoInteriorMutability,
    Owner::Slice: Slice<S>,
    S: ?Sized + fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Debug::fmt(self.0.as_slice(), f)
    }
}

impl<Owner, S> fmt::Display for OwnedSlice<Owner, S>
where
    Owner: SliceOwner + NoInteriorMutability,
    Owner::Slice: Slice<S>,
    S: ?Sized + fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(self.0.as_slice(), f)
    }
}