use std::borrow::*;
pub enum Calf<'borrow, BorrowedT> {
Borrowed(&'borrow BorrowedT),
Owned(BorrowedT),
}
impl<'borrow, BorrowedT> Calf<'borrow, BorrowedT> {
pub fn is_borrowed(&self) -> bool {
matches!(self, Self::Borrowed(_))
}
pub fn is_owned(&self) -> bool {
matches!(self, Self::Owned(_))
}
}
impl<'borrow, BorrowedT> Borrow<BorrowedT> for Calf<'borrow, BorrowedT> {
fn borrow(&self) -> &BorrowedT {
match self {
Self::Owned(owned) => owned,
Self::Borrowed(borrowed) => *borrowed,
}
}
}
impl<'borrow, BorrowedT, OwnedT> Calf<'borrow, BorrowedT>
where
BorrowedT: ToOwned<Owned = OwnedT>,
{
pub fn into_owned(self) -> <BorrowedT as ToOwned>::Owned {
match self {
Self::Owned(owned) => owned.to_owned(),
Self::Borrowed(borrowed) => borrowed.to_owned(),
}
}
}
impl<'borrow, BorrowedT> BorrowMut<BorrowedT> for Calf<'borrow, BorrowedT>
where
&'borrow BorrowedT: AsMut<&'borrow mut BorrowedT>,
{
fn borrow_mut(&mut self) -> &mut BorrowedT {
match self {
Self::Owned(owned) => owned,
Self::Borrowed(borrowed) => borrowed.as_mut(),
}
}
}
impl<'borrow, BorrowedT, OwnedT> ToOwned for Calf<'borrow, BorrowedT>
where
BorrowedT: ToOwned<Owned = OwnedT>,
OwnedT: Borrow<Self>,
{
type Owned = OwnedT;
fn to_owned(&self) -> OwnedT {
match self {
Self::Owned(owned) => owned.to_owned(),
Self::Borrowed(borrowed) => (*borrowed).to_owned(),
}
}
}
impl<'borrow, BorrowedT> From<Cow<'borrow, BorrowedT>> for Calf<'borrow, BorrowedT>
where
BorrowedT: ToOwned<Owned = BorrowedT>,
{
fn from(cow: Cow<'borrow, BorrowedT>) -> Self {
match cow {
Cow::Owned(owned) => Calf::Owned(owned),
Cow::Borrowed(borrowed) => Calf::Borrowed(borrowed),
}
}
}
impl<'borrow, BorrowedT> From<Calf<'borrow, BorrowedT>> for Cow<'borrow, BorrowedT>
where
BorrowedT: ToOwned<Owned = BorrowedT>,
{
fn from(calf: Calf<'borrow, BorrowedT>) -> Self {
match calf {
Calf::Owned(owned) => Cow::Owned(owned),
Calf::Borrowed(borrowed) => Cow::Borrowed(borrowed),
}
}
}