pub mod prelude {
pub use crate::Detach;
}
#[macro_export]
macro_rules! detach_run {
($item:expr, |$id:ident| $code:block) => {{
let mut $id = $item.take();
let out = (|| $code)();
$item.put($id);
out
}};
($item:expr, |$id:ident| $code:expr) => {{
let mut $id = $item.take();
let out = (|| $code)();
$item.put($id);
out
}};
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Detach<T>(Option<T>);
impl<T> Detach<T> {
pub fn new(inner: T) -> Self {
Self(Some(inner))
}
pub fn to_inner(self) -> T {
self.0.expect("detach exists-to_inner")
}
pub fn is_attached(&self) -> bool {
self.0.is_some()
}
pub fn take(&mut self) -> T {
std::mem::replace(&mut self.0, None).expect("detach exists-take")
}
pub fn put(&mut self, t: T) {
std::mem::replace(&mut self.0, Some(t));
}
}
impl<T> std::ops::Deref for Detach<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.as_ref().expect("detach exists-deref")
}
}
impl<T> std::ops::DerefMut for Detach<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut().expect("detach exists-deref-mut")
}
}
impl<T> std::borrow::Borrow<T> for Detach<T> {
fn borrow(&self) -> &T {
self.0.as_ref().expect("detach exists-borrow")
}
}
impl<T> std::borrow::BorrowMut<T> for Detach<T> {
fn borrow_mut(&mut self) -> &mut T {
self.0.as_mut().expect("detach exists-borrow-mut")
}
}
impl<T> std::convert::AsRef<T> for Detach<T> {
fn as_ref(&self) -> &T {
self.0.as_ref().expect("detach exists-as-ref")
}
}
impl<T> std::convert::AsMut<T> for Detach<T> {
fn as_mut(&mut self) -> &mut T {
self.0.as_mut().expect("detach exists-as-mut")
}
}
impl<T> std::convert::From<T> for Detach<T> {
fn from(t: T) -> Detach<T> {
Self(Some(t))
}
}