use core::{
cell::RefCell,
fmt,
ops::{Deref, DerefMut},
};
#[derive(Debug)]
pub struct FairlyUnsafeCell<T: ?Sized>(RefCell<T>);
impl<T> FairlyUnsafeCell<T> {
#[inline]
pub const fn new(value: T) -> Self {
Self(RefCell::new(value))
}
#[inline]
pub fn into_inner(self) -> T {
self.0.into_inner()
}
#[inline]
pub unsafe fn replace(&self, t: T) -> T {
self.0.replace(t)
}
#[inline]
pub unsafe fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
self.0.replace_with(f)
}
#[inline]
pub unsafe fn swap(&self, other: &Self) {
self.0.swap(&other.0)
}
}
impl<T: ?Sized> FairlyUnsafeCell<T> {
#[inline]
pub unsafe fn borrow(&self) -> Ref<'_, T> {
Ref(self.0.borrow())
}
#[inline]
pub unsafe fn borrow_mut(&self) -> RefMut<'_, T> {
RefMut(self.0.borrow_mut())
}
#[inline]
pub fn as_ptr(&self) -> *mut T {
self.0.as_ptr()
}
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
self.0.get_mut()
}
}
impl<T: Default> Default for FairlyUnsafeCell<T> {
#[inline]
fn default() -> FairlyUnsafeCell<T> {
Self(RefCell::default())
}
}
impl<T> From<T> for FairlyUnsafeCell<T> {
fn from(t: T) -> FairlyUnsafeCell<T> {
Self(RefCell::from(t))
}
}
#[derive(Debug)]
pub struct Ref<'b, T>(core::cell::Ref<'b, T>)
where
T: 'b + ?Sized;
impl<'b, T: ?Sized> Ref<'b, T> {
#[must_use]
#[inline]
pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
Ref(core::cell::Ref::clone(&orig.0))
}
#[inline]
pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
where
F: FnOnce(&T) -> &U,
{
Ref(core::cell::Ref::map(orig.0, f))
}
#[inline]
pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Result<Ref<'b, U>, Self>
where
F: FnOnce(&T) -> Option<&U>,
{
match core::cell::Ref::filter_map(orig.0, f) {
Ok(yay) => Ok(Ref(yay)),
Err(nay) => Err(Ref(nay)),
}
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
where
F: FnOnce(&T) -> (&U, &V),
{
let (a, b) = core::cell::Ref::map_split(orig.0, f);
(Ref(a), Ref(b))
}
}
impl<T: ?Sized> Deref for Ref<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.0.deref()
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for Ref<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug)]
pub struct RefMut<'b, T>(core::cell::RefMut<'b, T>)
where
T: 'b + ?Sized;
impl<'b, T: ?Sized> RefMut<'b, T> {
#[inline]
pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
where
F: FnOnce(&mut T) -> &mut U,
{
RefMut(core::cell::RefMut::map(orig.0, f))
}
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
orig: RefMut<'b, T>,
f: F,
) -> (RefMut<'b, U>, RefMut<'b, V>)
where
F: FnOnce(&mut T) -> (&mut U, &mut V),
{
let (a, b) = core::cell::RefMut::map_split(orig.0, f);
(RefMut(a), RefMut(b))
}
}
impl<T: ?Sized> Deref for RefMut<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.0.deref()
}
}
impl<T: ?Sized> DerefMut for RefMut<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.0.deref_mut()
}
}
impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}