use core::ops::Deref;
use self::RefKind::{Mut, Ref};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum RefKind<'a, T>
where
T: ?Sized + 'a,
{
Ref(&'a T),
Mut(&'a mut T),
}
impl<'a, T> RefKind<'a, T>
where
T: ?Sized + 'a,
{
#[inline]
pub fn is_ref(&self) -> bool {
matches!(self, Ref(_))
}
#[inline]
pub fn is_mut(&self) -> bool {
matches!(self, Mut(_))
}
#[inline]
pub fn get_ref(&self) -> &T {
self
}
#[inline]
pub fn get_mut(&mut self) -> Option<&mut T> {
match self {
Ref(_) => None,
Mut(unique) => Some(unique),
}
}
#[inline]
pub fn into_ref(self) -> &'a T {
match self {
Ref(shared) => shared,
Mut(unique) => unique,
}
}
#[inline]
pub fn into_mut(self) -> Option<&'a mut T> {
match self {
Ref(_) => None,
Mut(unique) => Some(unique),
}
}
#[inline]
#[track_caller]
pub fn unwrap_ref(self) -> &'a T {
match self {
Ref(shared) => shared,
Mut(_) => panic!("called `RefKind::unwrap_ref()` on a `RefKind::Mut` value"),
}
}
#[inline]
#[track_caller]
pub fn unwrap_mut(self) -> &'a mut T {
match self {
Ref(_) => panic!("called `RefKind::unwrap_mut()` on a `RefKind::Ref` value"),
Mut(unique) => unique,
}
}
}
impl<'a, T> From<&'a T> for RefKind<'a, T>
where
T: ?Sized + 'a,
{
#[inline]
fn from(shared: &'a T) -> Self {
Ref(shared)
}
}
impl<'a, T> From<&'a mut T> for RefKind<'a, T>
where
T: ?Sized + 'a,
{
#[inline]
fn from(unique: &'a mut T) -> Self {
Mut(unique)
}
}
impl<'a, T> Deref for RefKind<'a, T>
where
T: ?Sized + 'a,
{
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Ref(shared) => shared,
Mut(unique) => unique,
}
}
}
impl<'a, T, R> AsRef<R> for RefKind<'a, T>
where
T: ?Sized + 'a,
R: ?Sized,
<RefKind<'a, T> as Deref>::Target: AsRef<R>,
{
fn as_ref(&self) -> &R {
self.deref().as_ref()
}
}