use std::future::Future;
use crate::{Promise, PromiseRejection, State};
impl<T, E> Promise<T, E>
where
E: PromiseRejection,
{
pub fn lazy<F>(future: F) -> Self
where
F: Future<Output = Result<T, E>> + Send + 'static,
{
Self {
state: State::Pending(Box::pin(future)),
}
}
}
#[cfg(test)]
mod tests {
use std::{
future::Future,
pin::Pin,
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
task::{Context, Poll, Waker},
};
use crate::{Promise, PromiseRejection, TaskFailure};
#[derive(Debug)]
enum E {
AlreadyConsumed,
Fail,
}
impl PromiseRejection for E {
fn already_consumed() -> Self {
Self::AlreadyConsumed
}
fn task_failed(_: TaskFailure) -> Self {
Self::Fail
}
}
fn cx() -> Context<'static> {
Context::from_waker(Waker::noop())
}
#[test]
fn does_not_poll_on_construction() {
struct Counter {
count: Arc<AtomicUsize>,
}
impl Future for Counter {
type Output = Result<(), E>;
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
self.count.fetch_add(1, Ordering::Relaxed);
Poll::Ready(Ok(()))
}
}
let count = Arc::new(AtomicUsize::new(0));
let mut promise: Promise<(), E> = Promise::lazy(Counter {
count: count.clone(),
});
assert_eq!(count.load(Ordering::Relaxed), 0);
assert!(promise.is_pending());
promise.poll(&mut cx());
assert_eq!(count.load(Ordering::Relaxed), 1);
}
}