use crate::callback::{Interval, Timeout};
use futures_channel::{mpsc, oneshot};
use futures_core::stream::Stream;
use std::convert::TryFrom;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
use wasm_bindgen::prelude::*;
#[derive(Debug)]
#[must_use = "futures do nothing unless polled or spawned"]
pub struct TimeoutFuture {
_inner: Timeout,
rx: oneshot::Receiver<()>,
}
impl TimeoutFuture {
pub fn new(millis: u32) -> TimeoutFuture {
let (tx, rx) = oneshot::channel();
let inner = Timeout::new(millis, move || {
tx.send(()).unwrap_throw();
});
TimeoutFuture { _inner: inner, rx }
}
}
pub fn sleep(dur: Duration) -> TimeoutFuture {
let millis = u32::try_from(dur.as_millis())
.expect_throw("failed to cast the duration into a u32 with Duration::as_millis.");
TimeoutFuture::new(millis)
}
impl Future for TimeoutFuture {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
Future::poll(Pin::new(&mut self.rx), cx).map(|t| t.unwrap_throw())
}
}
#[derive(Debug)]
#[must_use = "streams do nothing unless polled or spawned"]
pub struct IntervalStream {
receiver: mpsc::UnboundedReceiver<()>,
_inner: Interval,
}
impl IntervalStream {
pub fn new(millis: u32) -> IntervalStream {
let (sender, receiver) = mpsc::unbounded();
let inner = Interval::new(millis, move || {
sender.unbounded_send(()).unwrap_throw();
});
IntervalStream {
receiver,
_inner: inner,
}
}
}
impl Stream for IntervalStream {
type Item = ();
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
Stream::poll_next(Pin::new(&mut self.receiver), cx)
}
}