use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
pub(crate) enum Boo<'a, T> {
Owned(T),
Borrowed(&'a mut T),
}
impl<T: Debug> Debug for Boo<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Owned(arg0) => f.debug_tuple("Owned").field(arg0).finish(),
Self::Borrowed(arg0) => f.debug_tuple("Borrowed").field(arg0).finish(),
}
}
}
impl<'a, T> From<&'a mut T> for Boo<'a, T> {
fn from(other: &'a mut T) -> Self {
Self::Borrowed(other)
}
}
impl<'a, T> From<T> for Boo<'a, T> {
fn from(other: T) -> Self {
Self::Owned(other)
}
}
impl<'a, T> Deref for Boo<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Boo::Owned(o) => o,
Boo::Borrowed(b) => &**b,
}
}
}
impl<'a, T> DerefMut for Boo<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Boo::Owned(o) => &mut *o,
Boo::Borrowed(b) => *b,
}
}
}
impl<'a, T> AsRef<T> for Boo<'a, T> {
fn as_ref(&self) -> &T {
match self {
Boo::Owned(o) => o,
Boo::Borrowed(b) => &**b,
}
}
}
impl<'a, T> AsMut<T> for Boo<'a, T> {
fn as_mut(&mut self) -> &mut T {
match self {
Boo::Owned(o) => &mut *o,
Boo::Borrowed(b) => *b,
}
}
}
impl<T: PartialEq> PartialEq for Boo<'_, T> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Owned(l0), Self::Owned(r0)) => l0 == r0,
(Self::Borrowed(l0), Self::Borrowed(r0)) => l0 == r0,
(Self::Borrowed(l0), Self::Owned(r0)) => *l0 == r0,
(Self::Owned(l0), Self::Borrowed(r0)) => l0 == *r0,
}
}
}