use std::ops::{Deref, DerefMut};
use crate::{
t_alloc, IndexedIter, IoBuf, IoBufMut, IoSlice, IoSliceMut, OwnedIterator, SetBufInit,
};
pub enum MaybeOwned<'a, T> {
Owned(T),
Borrowed(&'a T),
}
impl<T> Deref for MaybeOwned<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
MaybeOwned::Owned(t) => t,
MaybeOwned::Borrowed(t) => t,
}
}
}
pub enum MaybeOwnedMut<'a, T> {
Owned(T),
Borrowed(&'a mut T),
}
impl<T> Deref for MaybeOwnedMut<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
MaybeOwnedMut::Owned(t) => t,
MaybeOwnedMut::Borrowed(t) => t,
}
}
}
impl<T> DerefMut for MaybeOwnedMut<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
MaybeOwnedMut::Owned(t) => t,
MaybeOwnedMut::Borrowed(t) => t,
}
}
}
pub trait IoVectoredBuf: 'static {
type Buf: IoBuf;
type OwnedIter: OwnedIterator<Inner = Self> + IoBuf;
unsafe fn io_slices(&self) -> Vec<IoSlice> {
self.iter_buf().map(|buf| buf.as_io_slice()).collect()
}
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, Self::Buf>>;
fn owned_iter(self) -> Result<Self::OwnedIter, Self>
where
Self: Sized;
}
impl<T: IoBuf> IoVectoredBuf for &'static [T] {
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
impl<T: IoBuf> IoVectoredBuf for &'static mut [T] {
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
impl<T: IoBuf, const N: usize> IoVectoredBuf for [T; N] {
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
impl<T: IoBuf, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static> IoVectoredBuf
for t_alloc!(Vec, T, A)
{
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
#[cfg(feature = "arrayvec")]
impl<T: IoBuf, const N: usize> IoVectoredBuf for arrayvec::ArrayVec<T, N> {
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
#[cfg(feature = "smallvec")]
impl<T: IoBuf, const N: usize> IoVectoredBuf for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
type Buf = T;
type OwnedIter = IndexedIter<Self>;
fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}
fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}
pub trait IoVectoredBufMut: IoVectoredBuf<Buf: IoBufMut, OwnedIter: IoBufMut> + SetBufInit {
unsafe fn io_slices_mut(&mut self) -> Vec<IoSliceMut> {
self.iter_buf_mut()
.map(|mut buf| buf.as_io_slice_mut())
.collect()
}
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>>;
}
impl<T: IoBufMut> IoVectoredBufMut for &'static mut [T] {
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}
impl<T: IoBufMut, const N: usize> IoVectoredBufMut for [T; N] {
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}
impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: std::alloc::Allocator + 'static>
IoVectoredBufMut for t_alloc!(Vec, T, A)
{
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}
#[cfg(feature = "arrayvec")]
impl<T: IoBufMut, const N: usize> IoVectoredBufMut for arrayvec::ArrayVec<T, N> {
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}
#[cfg(feature = "smallvec")]
impl<T: IoBufMut, const N: usize> IoVectoredBufMut for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}