use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
enum FutureState<T, E> {
Promised,
Ok(T),
Err(E),
}
#[derive(Debug)]
pub struct FutureInner<T, E> {
state: FutureState<T, E>,
}
impl<T, E> FutureInner<T, E> {
fn promised() -> FutureInner<T, E> {
FutureInner {
state: FutureState::Promised,
}
}
fn from_val(val: T) -> FutureInner<T, E> {
FutureInner {
state: FutureState::Ok(val),
}
}
fn from_err(err: E) -> FutureInner<T, E> {
FutureInner {
state: FutureState::Err(err),
}
}
fn unwrap(self) -> T {
match self.state {
FutureState::Ok(val) => val,
_ => panic!("unwrap failed"),
}
}
fn unwrap_err(self) -> E {
match self.state {
FutureState::Err(err) => err,
_ => panic!("unwrap failed"),
}
}
fn expect(self, _msg: &str) -> T {
match self.state {
FutureState::Ok(val) => val,
_ => panic!("expect failed"),
}
}
fn is_promised(&self) -> bool {
match self.state {
FutureState::Promised => true,
_ => false,
}
}
fn is_err(&self) -> bool {
match self.state {
FutureState::Err(_) => true,
_ => false,
}
}
fn is_ok(&self) -> bool {
match self.state {
FutureState::Ok(_) => true,
_ => false,
}
}
fn ok(self) -> Option<T> {
match self.state {
FutureState::Ok(val) => Some(val),
_ => None,
}
}
fn err(self) -> Option<E> {
match self.state {
FutureState::Err(err) => Some(err),
_ => None,
}
}
fn set_ok(&mut self, val: T) {
assert!(self.is_promised());
self.state = FutureState::Ok(val);
}
fn set_err(&mut self, err: E) {
assert!(self.is_promised());
self.state = FutureState::Err(err);
}
}
pub struct Future<T, E> {
inner: Rc<RefCell<FutureInner<T, E>>>,
}
impl<T, E> Future<T, E> {
pub fn promised() -> (Future<T, E>, Promise<T, E>) {
let inner = Rc::new(RefCell::new(FutureInner::promised()));
let future = Future::new(inner.clone());
let promise = Promise::new(inner);
(future, promise)
}
pub fn from_val(val: T) -> Future<T, E> {
let inner = Rc::new(RefCell::new(FutureInner::from_val(val)));
Future::new(inner.clone())
}
pub fn from_err(err: E) -> Future<T, E> {
Future::new(Rc::new(RefCell::new(FutureInner::from_err(err))))
}
fn new(inner: Rc<RefCell<FutureInner<T, E>>>) -> Future<T, E> {
Future {
inner: inner,
}
}
pub fn is_promised(&self) -> bool {
self.inner.borrow().is_promised()
}
pub fn is_ok(&self) -> bool {
self.inner.borrow().is_ok()
}
pub fn is_err(&self) -> bool {
self.inner.borrow().is_err()
}
pub fn err(self) -> Option<E> {
match Rc::try_unwrap(self.inner) {
Ok(ref_cell) => ref_cell.into_inner().err(),
_ => None
}
}
pub fn ok(self) -> Option<T> {
match Rc::try_unwrap(self.inner) {
Ok(ref_cell) => ref_cell.into_inner().ok(),
_ => None
}
}
pub fn unwrap_err(self) -> E {
match Rc::try_unwrap(self.inner) {
Ok(ref_cell) => ref_cell.into_inner().unwrap_err(),
_ => panic!("could not unwrap inner")
}
}
pub fn unwrap(self) -> T {
match Rc::try_unwrap(self.inner) {
Ok(ref_cell) => ref_cell.into_inner().unwrap(),
_ => panic!("could not unwrap inner")
}
}
}
pub struct Promise<T, E> {
inner: Rc<RefCell<FutureInner<T, E>>>,
}
impl<T, E> Promise<T, E> {
fn new(inner: Rc<RefCell<FutureInner<T, E>>>) -> Promise<T, E> {
Promise {
inner: inner,
}
}
pub fn resolve(self, res: Result<T, E>) {
match res {
Ok(val) => self.inner.borrow_mut().set_ok(val),
Err(err) => self.inner.borrow_mut().set_err(err),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn future_ok() {
let f : Future<bool, ()> = Future::from_val(true);
assert!(f.is_ok());
assert!(!f.is_err());
assert!(!f.is_promised());
assert!(f.ok().unwrap());
}
#[test]
fn future_unwrap() {
let f : Future<bool, ()> = Future::from_val(true);
assert!(f.unwrap());
}
#[test]
fn future_err() {
let f : Future<(), bool> = Future::from_err(true);
assert!(f.is_err());
assert!(!f.is_ok());
assert!(!f.is_promised());
assert!(f.err().unwrap());
}
#[test]
fn future_unwrap_err() {
let f : Future<(), bool> = Future::from_err(true);
assert!(f.unwrap_err());
}
#[test]
fn future_promise_ok() {
let (f, p): (Future<bool, ()>, _) = Future::promised();
assert!(f.is_promised());
p.resolve(Ok(true));
assert!(f.is_ok());
assert!(f.unwrap());
}
#[test]
fn future_promise_err() {
let (f, p): (Future<(), bool>, _) = Future::promised();
assert!(f.is_promised());
p.resolve(Err(true));
assert!(f.is_err());
assert!(f.unwrap_err());
}
#[test]
#[should_panic]
fn future_ok_unwrap_err() {
let f: Future<bool, ()> = Future::from_val(false);
f.unwrap_err();
}
#[test]
#[should_panic]
fn future_promised_unwrap_err() {
let (f, _): (Future<bool, ()>, _) = Future::promised();
f.unwrap_err();
}
#[test]
#[should_panic]
fn future_err_unwrap() {
let f: Future<(), bool> = Future::from_err(false);
f.unwrap();
}
#[test]
#[should_panic]
fn future_promised_unwrap() {
let (f, _): (Future<bool, ()>, _) = Future::promised();
f.unwrap();
}
}