use crate::Index;
use std::{
cell::{Ref, RefCell, RefMut},
ops,
rc::Rc,
};
#[derive(Debug)]
pub enum IndexRef<'idx> {
Direct(&'idx mut Index),
Shared(Rc<RefCell<Index>>),
}
pub enum Guard<'a> {
Raw(&'a Index),
RefCell(Ref<'a, Index>),
}
impl<'a> ops::Deref for Guard<'a> {
type Target = Index;
fn deref(&self) -> &Self::Target {
match self {
Guard::Raw(r) => r,
Guard::RefCell(r) => r.deref(),
}
}
}
pub enum MutGuard<'a> {
Raw(&'a mut Index),
RefCell(RefMut<'a, Index>),
}
impl<'a> ops::Deref for MutGuard<'a> {
type Target = Index;
fn deref(&self) -> &Self::Target {
match self {
MutGuard::Raw(r) => r,
MutGuard::RefCell(r) => r.deref(),
}
}
}
impl<'a> ops::DerefMut for MutGuard<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
MutGuard::Raw(r) => r,
MutGuard::RefCell(r) => r.deref_mut(),
}
}
}
impl<'idx> IndexRef<'idx> {
pub fn get(&self) -> Guard<'_> {
match self {
IndexRef::Direct(index) => Guard::Raw(&**index),
IndexRef::Shared(ref_cell) => {
let r = ref_cell.borrow();
Guard::RefCell(r)
}
}
}
pub fn get_mut(&mut self) -> MutGuard<'_> {
match self {
IndexRef::Direct(index) => MutGuard::Raw(*index),
IndexRef::Shared(ref_cell) => {
let r = ref_cell.borrow_mut();
MutGuard::RefCell(r)
}
}
}
}