use std::borrow::{Borrow, BorrowMut};
use std::cmp::{Ord, Ordering, PartialOrd};
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
pub trait Borrowed {
type Owned: Borrow<Self>;
}
impl<T: Sized> Borrowed for T {
type Owned = T;
}
impl Borrowed for str {
type Owned = String;
}
impl<T> Borrowed for [T] {
type Owned = Vec<T>;
}
pub enum Mown<'a, T: ?Sized + Borrowed> {
Owned(T::Owned),
Borrowed(&'a T),
}
impl<'a, T: ?Sized + Borrowed> Mown<'a, T> {
pub fn is_owned(&self) -> bool {
match self {
Mown::Owned(_) => true,
Mown::Borrowed(_) => false,
}
}
pub fn is_borrowed(&self) -> bool {
match self {
Mown::Owned(_) => false,
Mown::Borrowed(_) => true,
}
}
pub fn as_mut(&mut self) -> Option<&mut T>
where
T::Owned: BorrowMut<T>,
{
match self {
Mown::Owned(t) => Some(t.borrow_mut()),
Mown::Borrowed(_) => None,
}
}
pub fn into_owned(self) -> <T as Borrowed>::Owned
where
T: ToOwned<Owned = <T as Borrowed>::Owned>,
{
match self {
Self::Borrowed(t) => t.to_owned(),
Self::Owned(t) => t,
}
}
}
impl<'a, T: ?Sized + Borrowed> AsRef<T> for Mown<'a, T> {
fn as_ref(&self) -> &T {
match self {
Mown::Owned(t) => t.borrow(),
Mown::Borrowed(t) => t,
}
}
}
impl<'a, T: ?Sized + Borrowed> Deref for Mown<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.as_ref()
}
}
impl<'a, T: ?Sized + Borrowed + PartialEq> PartialEq for Mown<'a, T> {
fn eq(&self, other: &Mown<'a, T>) -> bool {
self.as_ref() == other.as_ref()
}
}
impl<'a, T: ?Sized + Borrowed + Eq> Eq for Mown<'a, T> {}
impl<'a, T: ?Sized + Borrowed + PartialOrd> PartialOrd for Mown<'a, T> {
fn partial_cmp(&self, other: &Mown<'a, T>) -> Option<Ordering> {
self.as_ref().partial_cmp(other)
}
}
impl<'a, T: ?Sized + Borrowed + Ord> Ord for Mown<'a, T> {
fn cmp(&self, other: &Mown<'a, T>) -> Ordering {
self.as_ref().cmp(other)
}
}
impl<'a, T: ?Sized + Borrowed + Hash> Hash for Mown<'a, T> {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_ref().hash(hasher)
}
}
impl<'a, T: ?Sized + Borrowed + Display> Display for Mown<'a, T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl<'a, T: ?Sized + Borrowed + Debug> Debug for Mown<'a, T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl<'a, T: ?Sized + Borrowed, Q: Borrow<T>> From<&'a Q> for Mown<'a, T> {
fn from(r: &'a Q) -> Mown<'a, T> {
Mown::Borrowed(r.borrow())
}
}
pub enum MownMut<'a, T: ?Sized + Borrowed> {
Owned(T::Owned),
Borrowed(&'a mut T),
}
impl<'a, T: ?Sized + Borrowed> MownMut<'a, T> {
pub fn is_owned(&self) -> bool {
match self {
MownMut::Owned(_) => true,
MownMut::Borrowed(_) => false,
}
}
pub fn is_borrowed(&self) -> bool {
match self {
MownMut::Owned(_) => false,
MownMut::Borrowed(_) => true,
}
}
pub fn into_owned(self) -> <T as Borrowed>::Owned
where
T: ToOwned<Owned = <T as Borrowed>::Owned>,
{
match self {
Self::Borrowed(t) => t.to_owned(),
Self::Owned(t) => t,
}
}
}
impl<'a, T: ?Sized + Borrowed> AsRef<T> for MownMut<'a, T> {
fn as_ref(&self) -> &T {
match self {
MownMut::Owned(t) => t.borrow(),
MownMut::Borrowed(t) => t,
}
}
}
impl<'a, T: ?Sized + Borrowed> AsMut<T> for MownMut<'a, T>
where
T::Owned: BorrowMut<T>,
{
fn as_mut(&mut self) -> &mut T {
match self {
MownMut::Owned(t) => t.borrow_mut(),
MownMut::Borrowed(t) => t,
}
}
}
impl<'a, T: ?Sized + Borrowed> Deref for MownMut<'a, T> {
type Target = T;
fn deref(&self) -> &T {
self.as_ref()
}
}
impl<'a, T: ?Sized + Borrowed> DerefMut for MownMut<'a, T>
where
T::Owned: BorrowMut<T>,
{
fn deref_mut(&mut self) -> &mut T {
self.as_mut()
}
}
impl<'a, T: ?Sized + Borrowed + PartialEq> PartialEq for MownMut<'a, T> {
fn eq(&self, other: &MownMut<'a, T>) -> bool {
self.as_ref() == other.as_ref()
}
}
impl<'a, T: ?Sized + Borrowed + Eq> Eq for MownMut<'a, T> {}
impl<'a, T: ?Sized + Borrowed + PartialOrd> PartialOrd for MownMut<'a, T> {
fn partial_cmp(&self, other: &MownMut<'a, T>) -> Option<Ordering> {
self.as_ref().partial_cmp(other)
}
}
impl<'a, T: ?Sized + Borrowed + Ord> Ord for MownMut<'a, T> {
fn cmp(&self, other: &MownMut<'a, T>) -> Ordering {
self.as_ref().cmp(other)
}
}
impl<'a, T: ?Sized + Borrowed + Hash> Hash for MownMut<'a, T> {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.as_ref().hash(hasher)
}
}
impl<'a, T: ?Sized + Borrowed + Display> Display for MownMut<'a, T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl<'a, T: ?Sized + Borrowed + Debug> Debug for MownMut<'a, T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.as_ref().fmt(f)
}
}
impl<'a, T: ?Sized + Borrowed, Q: BorrowMut<T>> From<&'a mut Q> for MownMut<'a, T> {
fn from(r: &'a mut Q) -> MownMut<'a, T> {
MownMut::Borrowed(r.borrow_mut())
}
}