#![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use core::borrow::{Borrow, BorrowMut};
pub mod to_owned_stub;
#[cfg(not(feature = "alloc"))]
use crate::to_owned_stub::ToOwnedStub as ToOwned;
#[cfg(feature = "alloc")]
use alloc::borrow::{Cow, ToOwned};
pub trait AsIs: Sized + Borrow<Self::Is> {
type Is: ?Sized + ToOwned;
#[allow(clippy::wrong_self_convention)]
fn as_is<'a>(self) -> Is<'a, Self::Is>
where
Self: 'a;
fn borrow_or_clone<B: ?Sized>(&self) -> IsCow<'_, B>
where
Self::Is: Borrow<B>,
Owned<Self>: Borrow<B>,
B: ToOwned<Owned = Owned<Self>>,
{
IsCow::Borrowed(self.borrow().borrow())
}
fn into_is<'a, B: ?Sized>(self) -> Is<'a, B>
where
Self: 'a,
Self::Is: Borrow<B> + BorrowMut<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.as_is() {
Is::Owned(x) => Is::Owned(x),
Is::Borrowed(x) => Is::Borrowed(x.borrow()),
Is::MutBorrowed(x) => Is::MutBorrowed(x.borrow_mut()),
}
}
fn into_is_cow<'a, B: ?Sized>(self) -> IsCow<'a, B>
where
Self: 'a,
Self::Is: Borrow<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.as_is() {
Is::Owned(x) => IsCow::Owned(x),
Is::Borrowed(x) => IsCow::Borrowed(x.borrow()),
Is::MutBorrowed(x) => IsCow::Borrowed((*x).borrow()),
}
}
fn try_into_is_mut<'a, B: ?Sized>(self) -> Result<IsMut<'a, B>, Is<'a, Self::Is>>
where
Self: 'a,
Self::Is: BorrowMut<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.as_is() {
Is::Owned(x) => Ok(IsMut::Owned(x)),
Is::Borrowed(x) => Err(Is::Borrowed(x)),
Is::MutBorrowed(x) => Ok(IsMut::MutBorrowed(x.borrow_mut())),
}
}
fn try_into_owned<'a>(self) -> Result<Owned<Self>, Is<'a, Self::Is>>
where
Self: 'a,
{
match self.as_is() {
Is::Owned(x) => Ok(x),
Is::Borrowed(x) => Err(Is::Borrowed(x)),
Is::MutBorrowed(x) => Err(Is::MutBorrowed(x)),
}
}
#[cfg(feature = "alloc")]
fn into_cow<'a, B: ?Sized>(self) -> Cow<'a, B>
where
Self: 'a,
Self::Is: Borrow<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.as_is() {
Is::Owned(x) => Cow::Owned(x),
Is::Borrowed(x) => Cow::Borrowed(x.borrow()),
Is::MutBorrowed(x) => Cow::Borrowed((*x).borrow()),
}
}
}
pub trait AsIsMut: AsIs + BorrowMut<Self::Is> {
#[allow(clippy::wrong_self_convention)]
fn as_is_mut<'a>(self) -> IsMut<'a, Self::Is>
where
Self: 'a,
{
match self.as_is() {
Is::Owned(x) => IsMut::Owned(x),
Is::Borrowed(_) => unreachable!(),
Is::MutBorrowed(x) => IsMut::MutBorrowed(x),
}
}
fn borrow_mut_or_clone<B: ?Sized>(&mut self) -> IsMut<'_, B>
where
Self::Is: BorrowMut<B>,
Owned<Self>: BorrowMut<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.borrow_or_clone() {
IsCow::Owned(x) => IsMut::Owned(x),
IsCow::Borrowed(_) => IsMut::MutBorrowed(self.borrow_mut().borrow_mut()),
}
}
fn into_is_mut<'a, B: ?Sized>(self) -> IsMut<'a, B>
where
Self: 'a,
Self::Is: BorrowMut<B>,
B: ToOwned<Owned = Owned<Self>>,
{
match self.as_is_mut() {
IsMut::Owned(x) => IsMut::Owned(x),
IsMut::MutBorrowed(x) => IsMut::MutBorrowed(x.borrow_mut()),
}
}
}
pub type Owned<T> = <<T as AsIs>::Is as ToOwned>::Owned;
impl<T: ?Sized> AsIs for &T
where
T: ToOwned,
T::Owned: AsIs<Is = T::Owned>,
{
type Is = T;
fn as_is<'a>(self) -> Is<'a, Self::Is>
where
Self: 'a,
{
Is::Borrowed(self)
}
}
impl<T: ?Sized> AsIs for &mut T
where
T: ToOwned,
T::Owned: AsIs<Is = T::Owned>,
{
type Is = T;
fn as_is<'a>(self) -> Is<'a, Self::Is>
where
Self: 'a,
{
Is::MutBorrowed(self)
}
}
impl<T: ?Sized> AsIsMut for &mut T
where
T: ToOwned,
T::Owned: AsIs<Is = T::Owned>,
{
}
#[derive(Debug)]
pub enum Is<'a, T: ?Sized>
where
T: ToOwned,
{
Owned(T::Owned),
Borrowed(&'a T),
MutBorrowed(&'a mut T),
}
#[derive(Debug)]
pub enum IsCow<'a, T: ?Sized>
where
T: ToOwned,
{
Owned(T::Owned),
Borrowed(&'a T),
}
#[derive(Debug)]
pub enum IsMut<'a, T: ?Sized>
where
T: ToOwned,
{
Owned(T::Owned),
MutBorrowed(&'a mut T),
}
mod impl_for_foreign;
mod impl_for_is;
mod impl_for_is_cow;
mod impl_for_is_mut;