use std::ops::{Deref, DerefMut};
#[derive(Debug, PartialEq, Eq)]
pub enum OwnedOrMutRef<'r, T> {
Owned(T),
MutRef(&'r mut T),
}
impl<'r, T> OwnedOrMutRef<'r, T> {
pub fn reborrow(&mut self) -> OwnedOrMutRef<'_, T> {
match self {
OwnedOrMutRef::Owned(ref mut t) => OwnedOrMutRef::MutRef(t),
OwnedOrMutRef::MutRef(t) => OwnedOrMutRef::MutRef(t),
}
}
}
impl<'r, T> Deref for OwnedOrMutRef<'r, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
OwnedOrMutRef::Owned(t) => t,
OwnedOrMutRef::MutRef(t) => t,
}
}
}
impl<'r, T> DerefMut for OwnedOrMutRef<'r, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
OwnedOrMutRef::Owned(t) => t,
OwnedOrMutRef::MutRef(t) => t,
}
}
}
impl<'r, T> From<T> for OwnedOrMutRef<'r, T> {
fn from(v: T) -> Self {
Self::Owned(v)
}
}
impl<'r, T> From<&'r mut T> for OwnedOrMutRef<'r, T> {
fn from(v: &'r mut T) -> Self {
Self::MutRef(v)
}
}
#[cfg(test)]
mod tests {
use std::ops::{Deref, DerefMut};
use super::OwnedOrMutRef;
#[test]
fn debug() {
let owned_or_mut_ref = OwnedOrMutRef::Owned(123);
assert_eq!("Owned(123)", format!("{owned_or_mut_ref:?}"));
}
#[test]
fn reborrow() {
let mut owned = OwnedOrMutRef::Owned(123);
let mut n = 123;
let mut mut_ref = OwnedOrMutRef::MutRef(&mut n);
assert_eq!(OwnedOrMutRef::MutRef(&mut 123), owned.reborrow());
assert_eq!(OwnedOrMutRef::MutRef(&mut 123), mut_ref.reborrow());
}
#[test]
fn deref() {
let owned = OwnedOrMutRef::Owned(123);
let mut n = 123;
let mut_ref = OwnedOrMutRef::MutRef(&mut n);
assert_eq!(&123, Deref::deref(&owned));
assert_eq!(&123, Deref::deref(&mut_ref));
}
#[test]
fn deref_mut() {
let mut owned = OwnedOrMutRef::Owned(123);
let mut n = 123;
let mut mut_ref = OwnedOrMutRef::MutRef(&mut n);
assert_eq!(&mut 123, DerefMut::deref_mut(&mut owned));
assert_eq!(&mut 123, DerefMut::deref_mut(&mut mut_ref));
}
#[test]
fn from_t() {
let owned = OwnedOrMutRef::from(123);
assert_eq!(OwnedOrMutRef::Owned(123), owned);
}
#[test]
fn from_mut_ref() {
let mut n = 123;
let mut_ref_n = OwnedOrMutRef::<u32>::from(&mut n);
let mut m = 123;
let mut_ref_m = OwnedOrMutRef::MutRef(&mut m);
assert_eq!(mut_ref_n, mut_ref_m);
}
}