me-cell 0.1.0

Multi-entrance cell, for building tree structures (a helper crate for maomi)
Documentation
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::fmt;
use std::cell::UnsafeCell;

pub struct MeBorrowError {
    msg: &'static str
}
impl fmt::Debug for MeBorrowError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.msg)
    }
}
impl fmt::Display for MeBorrowError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.msg)
    }
}
impl std::error::Error for MeBorrowError {}

struct Ctx {
    is_mut: UnsafeCell<bool>,
    count: UnsafeCell<usize>,
}

pub struct MeCell<T> {
    ctx: Rc<Ctx>,
    content: UnsafeCell<T>,
}

impl<T> MeCell<T> {
    pub fn new_group(content: T) -> Self {
        Self {
            ctx: Rc::new(Ctx {
                is_mut: UnsafeCell::new(false),
                count: UnsafeCell::new(0),
            }),
            content: UnsafeCell::new(content),
        }
    }
    pub fn borrow(&self) -> MeRef<T> {
        unsafe {
            if *self.ctx.is_mut.get() { panic!("MeCell has been mutably borrowed") };
            *self.ctx.count.get() += 1;
        }
        MeRef { handle: MeRefHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &*self.content.get() } }
    }
    pub fn try_borrow(&self) -> Result<MeRef<T>, MeBorrowError> {
        unsafe {
            if *self.ctx.is_mut.get() { return Err(MeBorrowError { msg: "MeCell has been mutably borrowed" }) };
            *self.ctx.count.get() += 1;
        }
        Ok(MeRef { handle: MeRefHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &*self.content.get() } })
    }
    pub fn borrow_mut(&self) -> MeRefMut<T> {
        unsafe {
            if *self.ctx.is_mut.get() || *self.ctx.count.get() > 0 { panic!("MeCell has been borrowed") };
            *self.ctx.is_mut.get() = true;
        }
        MeRefMut { handle: MeRefMutHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &mut *self.content.get() } }
    }
    pub fn try_borrow_mut(&self) -> Result<MeRefMut<T>, MeBorrowError> {
        unsafe {
            if *self.ctx.is_mut.get() || *self.ctx.count.get() > 0 { return Err(MeBorrowError { msg: "MeCell has been borrowed" }) };
            *self.ctx.is_mut.get() = true;
        }
        Ok(MeRefMut { handle: MeRefMutHandle { is_source: true, ctx: &self.ctx }, content: unsafe { &mut *self.content.get() } })
    }
    pub fn borrow_with<'a: 'b, 'b, U>(&'b self, source: &'b MeRef<'a, U>) -> MeRef<'b, T> {
        source.another(self)
    }
    pub fn borrow_mut_with<'a: 'b, 'b, U>(&'b self, source: &'b mut MeRefMut<'a, U>) -> MeRefMut<'b, T> {
        source.another_mut(self)
    }
    pub unsafe fn borrow_mut_unsafe_with<'a: 'b, 'b, 'c, U>(&'c self, source: &'b mut MeRefMut<'a, U>) -> MeRefMut<'c, T> {
        source.another_mut_unsafe(self)
    }
    pub fn borrow_with_handle<'a: 'b, 'b>(&'b self, source: &'b MeRefHandle<'a>) -> MeRef<'b, T> {
        source.another(self)
    }
    pub fn borrow_mut_with_handle<'a: 'b, 'b>(&'b self, source: &'b mut MeRefMutHandle<'a>) -> MeRefMut<'b, T> {
        source.another_mut(self)
    }
    pub unsafe fn borrow_mut_unsafe_with_handle<'a: 'b, 'b, 'c>(&'c self, source: &'b mut MeRefMutHandle<'a>) -> MeRefMut<'c, T> {
        source.another_mut_unsafe(self)
    }
}

pub struct MeRefHandle<'a> {
    is_source: bool,
    ctx: &'a Rc<Ctx>,
}
impl<'a> MeRefHandle<'a> {
    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
        if !Rc::ptr_eq(&another.ctx, self.ctx) {
            panic!("A MeCell can only be borrowed with another MeCell in the same group");
        }
        MeRef { handle: MeRefHandle { is_source: false, ctx: self.ctx }, content: unsafe { &*another.content.get() } }
    }
    fn duplicate<'b>(&'b self) -> MeRefHandle<'b> where 'a: 'b {
        MeRefHandle { is_source: false, ctx: self.ctx }
    }
}
impl<'a> Drop for MeRefHandle<'a> {
    fn drop(&mut self) {
        if !self.is_source { return };
        let c = self.ctx.count.get();
        unsafe {
            *c -= 1;
        }
    }
}

pub struct MeRefMutHandle<'a> {
    is_source: bool,
    ctx: &'a Rc<Ctx>
}
impl<'a> MeRefMutHandle<'a> {
    pub fn entrance<U>(&mut self, content: U) -> MeCell<U> {
        MeCell {
            ctx: self.ctx.clone(),
            content: UnsafeCell::new(content),
        }
    }
    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
        if !Rc::ptr_eq(&another.ctx, self.ctx) {
            panic!("A MeCell can only be borrowed with another MeCell in the same group");
        }
        MeRef { handle: MeRefHandle { is_source: false, ctx: self.ctx }, content: unsafe { &*another.content.get() } }
    }
    pub fn another_mut<'b, U>(&'b mut self, another: &'b MeCell<U>) -> MeRefMut<'b, U> where 'a: 'b {
        if !Rc::ptr_eq(&another.ctx, self.ctx) {
            panic!("A MeCell can only be borrowed with another MeCell in the same group");
        }
        MeRefMut { handle: MeRefMutHandle { is_source: false, ctx: self.ctx }, content: unsafe { &mut *another.content.get() } }
    }
    fn duplicate<'b>(&'b self) -> MeRefMutHandle<'b> where 'a: 'b {
        MeRefMutHandle { is_source: false, ctx: self.ctx }
    }
    pub unsafe fn another_mut_unsafe<'b, 'c, U>(&'b mut self, another: &'c MeCell<U>) -> MeRefMut<'c, U> where 'a: 'b {
        if !Rc::ptr_eq(&another.ctx, self.ctx) {
            panic!("A MeCell can only be borrowed with another MeCell in the same group");
        }
        MeRefMut { handle: MeRefMutHandle { is_source: false, ctx: &another.ctx }, content: &mut *another.content.get() }
    }
}
impl<'a> Drop for MeRefMutHandle<'a> {
    fn drop(&mut self) {
        if !self.is_source { return };
        let is_mut = self.ctx.is_mut.get();
        unsafe {
            *is_mut = false;
        }
    }
}

pub struct MeRef<'a, T> {
    handle: MeRefHandle<'a>,
    content: &'a T,
}
impl<'a, T> MeRef<'a, T> {
    pub fn handle(&self) -> &MeRefHandle<'a> {
        &self.handle
    }
    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
        self.handle.another(another)
    }
    pub fn duplicate<'b>(&'b self) -> MeRef<'b, T> where 'a: 'b {
        MeRef {
            handle: self.handle.duplicate(),
            content: self.content,
        }
    }
    pub fn map<'b, U, F>(self, f: F) -> MeRef<'b, U> where 'a: 'b, F: FnOnce(&T) -> &U {
        MeRef { handle: self.handle, content: f(self.content) }
    }
}
impl<'a, T> Deref for MeRef<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        self.content
    }
}
impl<'a, T: fmt::Debug> fmt::Debug for MeRef<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self.content)
    }
}
impl<'a, T: fmt::Display> fmt::Display for MeRef<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.content)
    }
}

pub struct MeRefMut<'a, T> {
    handle: MeRefMutHandle<'a>,
    content: &'a mut T,
}
impl<'a, T> MeRefMut<'a, T> {
    pub fn handle_mut(&mut self) -> &mut MeRefMutHandle<'a> {
        &mut self.handle
    }
    pub fn entrance<U>(&mut self, content: U) -> MeCell<U> {
        self.handle.entrance(content)
    }
    pub fn another<'b, U>(&'b self, another: &'b MeCell<U>) -> MeRef<'b, U> where 'a: 'b {
        self.handle.another(another)
    }
    pub fn another_mut<'b, U>(&'b mut self, another: &'b MeCell<U>) -> MeRefMut<'b, U> where 'a: 'b {
        self.handle.another_mut(another)
    }
    pub unsafe fn another_mut_unsafe<'b, 'c, U>(&'b mut self, another: &'c MeCell<U>) -> MeRefMut<'c, U> where 'a: 'b {
        self.handle.another_mut_unsafe(another)
    }
    pub fn duplicate<'b>(&'b mut self) -> MeRefMut<'b, T> where 'a: 'b {
        MeRefMut {
            handle: self.handle.duplicate(),
            content: self.content,
        }
    }
    pub fn to_ref<'b>(&'b self) -> MeRef<'b, T> where 'a: 'b {
        MeRef { handle: MeRefHandle { is_source: false, ctx: self.handle.ctx }, content: &*self.content }
    }
    pub fn map<'b, U, F>(self, f: F) -> MeRefMut<'b, U> where 'a: 'b, F: FnOnce(&mut T) -> &mut U {
        MeRefMut { handle: self.handle, content: f(self.content) }
    }
}
impl<'a, T> Deref for MeRefMut<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        self.content
    }
}
impl<'a, T> DerefMut for MeRefMut<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        self.content
    }
}
impl<'a, T: fmt::Debug> fmt::Debug for MeRefMut<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self.content)
    }
}
impl<'a, T: fmt::Display> fmt::Display for MeRefMut<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.content)
    }
}