use core::fmt;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use crate::token::InvariantLifetime;
#[repr(transparent)]
pub struct MelinoeRef<'a, 'brand, T: ?Sized> {
value: &'a T,
_brand: InvariantLifetime<'brand>,
}
impl<'a, 'brand, T: ?Sized> MelinoeRef<'a, 'brand, T> {
#[inline]
pub(crate) fn new(value: &'a T) -> Self {
Self {
value,
_brand: PhantomData,
}
}
#[inline]
#[must_use]
pub const fn into_ref(self) -> &'a T {
self.value
}
#[inline]
pub fn map<U: ?Sized, F>(orig: Self, f: F) -> MelinoeRef<'a, 'brand, U>
where
F: FnOnce(&'a T) -> &'a U,
{
MelinoeRef::new(f(orig.value))
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
orig: Self,
f: F,
) -> (MelinoeRef<'a, 'brand, U>, MelinoeRef<'a, 'brand, V>)
where
F: FnOnce(&'a T) -> (&'a U, &'a V),
{
let (a, b) = f(orig.value);
(MelinoeRef::new(a), MelinoeRef::new(b))
}
}
impl<'a, 'brand, T: ?Sized> Deref for MelinoeRef<'a, 'brand, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'a, 'brand, T: ?Sized + fmt::Debug> fmt::Debug for MelinoeRef<'a, 'brand, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.value, f)
}
}
#[repr(transparent)]
pub struct MelinoeMut<'a, 'brand, T: ?Sized> {
value: &'a mut T,
_brand: InvariantLifetime<'brand>,
}
impl<'a, 'brand, T: ?Sized> MelinoeMut<'a, 'brand, T> {
#[inline]
pub(crate) fn new(value: &'a mut T) -> Self {
Self {
value,
_brand: PhantomData,
}
}
#[inline]
#[must_use]
pub fn into_mut(self) -> &'a mut T {
self.value
}
#[inline]
pub fn map<U: ?Sized, F>(orig: Self, f: F) -> MelinoeMut<'a, 'brand, U>
where
F: FnOnce(&'a mut T) -> &'a mut U,
{
MelinoeMut::new(f(orig.value))
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
orig: Self,
f: F,
) -> (MelinoeMut<'a, 'brand, U>, MelinoeMut<'a, 'brand, V>)
where
F: FnOnce(&'a mut T) -> (&'a mut U, &'a mut V),
{
let (a, b) = f(orig.value);
(MelinoeMut::new(a), MelinoeMut::new(b))
}
}
impl<'a, 'brand, T: ?Sized> Deref for MelinoeMut<'a, 'brand, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'a, 'brand, T: ?Sized> DerefMut for MelinoeMut<'a, 'brand, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.value
}
}
impl<'a, 'brand, T: ?Sized + fmt::Debug> fmt::Debug for MelinoeMut<'a, 'brand, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.value, f)
}
}