#![no_std]
#![deny(unsafe_code)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
extern crate alloc;
mod arc;
mod rc;
use alloc::{boxed::Box, vec::Vec};
use core::ops::Range;
pub use arc::ArcSlice;
pub use rc::RcSlice;
pub trait RcSliceContainer {
type Item;
const IS_SHRINKABLE: bool;
fn len(&self) -> usize;
fn get(&self, range: Range<usize>) -> Option<&[Self::Item]>;
fn get_mut(&mut self, range: Range<usize>) -> Option<&mut [Self::Item]>;
fn shrink_container_to_range(&mut self, keep_range: Range<usize>) -> Option<Range<usize>>;
}
impl<T> RcSliceContainer for [T] {
type Item = T;
const IS_SHRINKABLE: bool = false;
fn len(&self) -> usize {
self.len()
}
fn get(&self, range: Range<usize>) -> Option<&[T]> {
Self::get(self, range)
}
fn get_mut(&mut self, range: Range<usize>) -> Option<&mut [T]> {
Self::get_mut(self, range)
}
fn shrink_container_to_range(&mut self, _keep_range: Range<usize>) -> Option<Range<usize>> {
unimplemented!()
}
}
#[test]
fn test_slice_container_raw_array() {
use alloc::rc::Rc;
use RcSlice as Rcs;
let buffer: Rc<[u8]> = Rc::new([2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 1..4), [4, 6, 8]);
assert_eq!(*Rcs::new(&buffer, ..), [2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 0..=2), [2, 4, 6]);
assert_eq!(*Rcs::new(&buffer, 10..), []);
}
impl<T> RcSliceContainer for Box<[T]> {
type Item = T;
const IS_SHRINKABLE: bool = false;
fn len(&self) -> usize {
self.as_ref().len()
}
fn get(&self, range: Range<usize>) -> Option<&[Self::Item]> {
self.as_ref().get(range)
}
fn get_mut(&mut self, range: Range<usize>) -> Option<&mut [Self::Item]> {
self.as_mut().get_mut(range)
}
fn shrink_container_to_range(&mut self, _keep_range: Range<usize>) -> Option<Range<usize>> {
unimplemented!()
}
}
#[test]
fn test_slice_container_boxed_array() {
use alloc::rc::Rc;
use RcSlice as Rcs;
let buffer: Rc<Box<[u8]>> = Rc::new(Box::new([2, 4, 6, 8, 10]));
assert_eq!(*Rcs::new(&buffer, 1..4), [4, 6, 8]);
assert_eq!(*Rcs::new(&buffer, ..), [2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 0..=2), [2, 4, 6]);
assert_eq!(*Rcs::new(&buffer, 10..), []);
}
impl<T> RcSliceContainer for Vec<T> {
type Item = T;
const IS_SHRINKABLE: bool = true;
fn len(&self) -> usize {
self.len()
}
fn get(&self, range: Range<usize>) -> Option<&[T]> {
self.as_slice().get(range)
}
fn get_mut(&mut self, range: Range<usize>) -> Option<&mut [T]> {
self.as_mut_slice().get_mut(range)
}
fn shrink_container_to_range(&mut self, keep_range: Range<usize>) -> Option<Range<usize>> {
self.truncate(keep_range.end);
let mut cur_index = 0;
self.retain(|_| {
let ret = keep_range.contains(&cur_index);
cur_index += 1;
ret
});
self.shrink_to_fit();
Some(0..Self::len(self))
}
}
#[test]
fn test_slice_container_vec() {
use alloc::rc::Rc;
use alloc::vec;
use RcSlice as Rcs;
let buffer: Rc<Vec<u8>> = Rc::new(vec![2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 1..4), [4, 6, 8]);
assert_eq!(*Rcs::new(&buffer, ..), [2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 0..=2), [2, 4, 6]);
assert_eq!(*Rcs::new(&buffer, 10..), []);
let mut slice = Rcs::new(&buffer, 1..4);
core::mem::drop(buffer);
assert_eq!(Rc::strong_count(RcSlice::inner(&slice)), 1);
assert_eq!(*slice, [4, 6, 8]);
assert_eq!(**RcSlice::inner(&slice), [2, 4, 6, 8, 10]);
assert_eq!(RcSlice::shrink(&mut slice), true);
assert_eq!(*slice, [4, 6, 8]);
assert_eq!(**RcSlice::inner(&slice), [4, 6, 8]);
}
#[cfg(feature = "smallvec")]
impl<T: smallvec::Array> RcSliceContainer for smallvec::SmallVec<T> {
type Item = T::Item;
const IS_SHRINKABLE: bool = true;
fn len(&self) -> usize {
self.len()
}
fn get(&self, range: Range<usize>) -> Option<&[Self::Item]> {
self.as_slice().get(range)
}
fn get_mut(&mut self, range: Range<usize>) -> Option<&mut [Self::Item]> {
self.as_mut_slice().get_mut(range)
}
fn shrink_container_to_range(&mut self, keep_range: Range<usize>) -> Option<Range<usize>> {
if !self.spilled() {
return None;
}
self.truncate(keep_range.end);
let mut cur_index = 0;
self.retain(|_| {
let ret = keep_range.contains(&cur_index);
cur_index += 1;
ret
});
self.shrink_to_fit();
Some(0..Self::len(self))
}
}
#[cfg(feature = "smallvec")]
#[test]
fn test_slice_container_smallvec() {
use alloc::rc::Rc;
use alloc::vec;
use smallvec::SmallVec;
use RcSlice as Rcs;
let buffer: Rc<SmallVec<[u8; 4]>> = Rc::new(SmallVec::from_vec(vec![2, 4, 6, 8, 10]));
assert_eq!(*Rcs::new(&buffer, 1..4), [4, 6, 8]);
assert_eq!(*Rcs::new(&buffer, ..), [2, 4, 6, 8, 10]);
assert_eq!(*Rcs::new(&buffer, 0..=2), [2, 4, 6]);
assert_eq!(*Rcs::new(&buffer, 10..), []);
let mut slice = Rcs::new(&buffer, 1..4);
core::mem::drop(buffer);
assert_eq!(Rc::strong_count(RcSlice::inner(&slice)), 1);
assert_eq!(*slice, [4, 6, 8]);
assert_eq!(RcSlice::inner(&slice).as_ref().as_ref(), [2, 4, 6, 8, 10]);
assert_eq!(RcSlice::inner(&slice).spilled(), true);
assert_eq!(RcSlice::shrink(&mut slice), true);
assert_eq!(*slice, [4, 6, 8]);
assert_eq!(RcSlice::inner(&slice).as_ref().as_ref(), [4, 6, 8]);
assert_eq!(RcSlice::inner(&slice).spilled(), false);
}
#[deprecated(since = "0.4.0")]
pub type RcBytes = RcSlice<[u8]>;
#[deprecated(since = "0.4.0")]
pub type ArcBytes = ArcSlice<[u8]>;