yew/packages/yew-services/src/callback_test_util.rs
Muhammad Hamza 991abab7e1
Update Rust version for macro tests to 1.51 & enable const generics tests (#1801)
* update rust version for macro test to 1.51

* enable const generic tests

* run integration tests using MSRV

* am blind

* clippy, fmt

* apply suggestion
2021-03-30 22:35:21 +02:00

69 lines
1.5 KiB
Rust

#![cfg(test)]
use std::cell::RefCell;
use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll, Waker};
use yew::callback::*;
struct CallbackHandle<T> {
waker: Option<Waker>,
output: Option<T>,
}
impl<T> Default for CallbackHandle<T> {
fn default() -> Self {
CallbackHandle {
waker: None,
output: None,
}
}
}
pub struct CallbackFuture<T>(Rc<RefCell<CallbackHandle<T>>>);
impl<T> Clone for CallbackFuture<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> Default for CallbackFuture<T> {
fn default() -> Self {
Self(Rc::default())
}
}
impl<T: 'static> From<CallbackFuture<T>> for Callback<T> {
fn from(f: CallbackFuture<T>) -> Self {
Callback::from(move |r| f.finish(r))
}
}
impl<T> Future for CallbackFuture<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if let Some(output) = self.ready() {
Poll::Ready(output)
} else {
let handle = &self.0;
handle.borrow_mut().waker = Some(cx.waker().clone());
Poll::Pending
}
}
}
impl<T> CallbackFuture<T> {
pub fn ready(&self) -> Option<T> {
self.0.borrow_mut().output.take()
}
fn finish(&self, output: T) {
self.0.borrow_mut().output = Some(output);
if let Some(waker) = self.0.borrow_mut().waker.take() {
waker.wake();
}
}
}