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)
}
}