#![doc(hidden)] use std::ops::{Deref, DerefMut}; pub enum Suspendable { Active(T), Suspended, } impl Suspendable { pub fn new(t: T) -> Self { Suspendable::Active(t) } #[inline(always)] pub fn suspend(&mut self) -> Self { match self { Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended), Suspendable::Suspended => panic!("Attempt to suspend suspended Suspendable"), } } #[inline(always)] pub fn resume(&mut self, other: Self) { match self { Suspendable::Suspended => match other { Suspendable::Active(_) => *self = other, Suspendable::Suspended => panic!("Attempt to resume from suspended Suspendable"), }, Suspendable::Active(_) => panic!("Attempt to resume non-suspended Suspendable"), } } #[inline(always)] pub fn take(self) -> T { match self { Suspendable::Active(t) => t, Suspendable::Suspended => panic!("Attempt to take from suspended Suspendable"), } } } impl Deref for Suspendable { type Target = T; #[inline(always)] fn deref(&self) -> &Self::Target { match self { Suspendable::Suspended => panic!("Suspended Suspendable at deref"), Suspendable::Active(t) => t, } } } impl DerefMut for Suspendable { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { match self { Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"), Suspendable::Active(t) => t, } } }