use alloc::borrow::Cow;
use super::{CellSliceExt, MelinoeCell};
use crate::token::ReadPermit;
mod sealed {
pub trait Sealed {}
}
pub trait CowPolicy: sealed::Sealed + Copy {
#[must_use]
fn cow<T: Clone>(slice: &[T]) -> Cow<'_, [T]>;
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Borrowed;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Retained;
impl sealed::Sealed for Borrowed {}
impl sealed::Sealed for Retained {}
impl CowPolicy for Borrowed {
#[inline]
fn cow<T: Clone>(slice: &[T]) -> Cow<'_, [T]> {
Cow::Borrowed(slice)
}
}
impl CowPolicy for Retained {
#[inline]
fn cow<T: Clone>(slice: &[T]) -> Cow<'_, [T]> {
Cow::Owned(slice.to_vec())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RetainDecision {
Borrow,
Retain,
}
impl RetainDecision {
#[inline]
fn cow<T: Clone>(self, slice: &[T]) -> Cow<'_, [T]> {
match self {
Self::Borrow => Borrowed::cow(slice),
Self::Retain => Retained::cow(slice),
}
}
}
pub trait CellCowExt<'brand, T: Clone> {
fn borrow_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a;
fn retain_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a;
fn borrow_cow_with<'a, P, C>(&'a self, permit: P, policy: C) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a,
C: CowPolicy;
fn borrow_cow_if<'a, P>(&'a self, permit: P, decision: RetainDecision) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a;
}
impl<'brand, T: Clone> CellCowExt<'brand, T> for [MelinoeCell<'brand, T>] {
#[inline]
fn borrow_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a,
{
Borrowed::cow(self.borrow_slice(permit))
}
#[inline]
fn retain_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a,
{
Retained::cow(self.borrow_slice(permit))
}
#[inline]
fn borrow_cow_with<'a, P, C>(&'a self, permit: P, _policy: C) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a,
C: CowPolicy,
{
let slice = self.borrow_slice(permit);
C::cow(slice)
}
#[inline]
fn borrow_cow_if<'a, P>(&'a self, permit: P, decision: RetainDecision) -> Cow<'a, [T]>
where
P: ReadPermit<'brand> + 'a,
{
let slice = self.borrow_slice(permit);
decision.cow(slice)
}
}