forked from syndicate-lang/preserves
61 lines
1.6 KiB
Rust
61 lines
1.6 KiB
Rust
use std::ops::{Deref, DerefMut};
|
|
|
|
pub enum Suspendable<T> {
|
|
Active(T),
|
|
Suspended,
|
|
}
|
|
|
|
impl<T> Suspendable<T> {
|
|
pub fn new(t: T) -> Self {
|
|
Suspendable::Active(t)
|
|
}
|
|
|
|
pub fn suspend(&mut self) -> Self {
|
|
match self {
|
|
Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended),
|
|
Suspendable::Suspended =>
|
|
panic!("Attempt to suspend suspended Suspendable"),
|
|
}
|
|
}
|
|
|
|
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"),
|
|
}
|
|
}
|
|
|
|
pub fn take(self) -> T {
|
|
match self {
|
|
Suspendable::Active(t) => t,
|
|
Suspendable::Suspended =>
|
|
panic!("Attempt to take from suspended Suspendable"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> Deref for Suspendable<T> {
|
|
type Target = T;
|
|
fn deref(&self) -> &Self::Target {
|
|
match self {
|
|
Suspendable::Suspended => panic!("Suspended Suspendable at deref"),
|
|
Suspendable::Active(t) => t
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> DerefMut for Suspendable<T> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
match self {
|
|
Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),
|
|
Suspendable::Active(t) => t
|
|
}
|
|
}
|
|
}
|