Callback constructor for FutureLink (#1272)

* initial implementation of #1271 callback constructor for FutureLink

* #1271 fix implementations to match function signature of trait

* #1271 fix failing build
This commit is contained in:
Luke Frisken 2020-06-21 13:03:29 +04:00 committed by GitHub
parent a49291a5b1
commit 125812da4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -8,14 +8,29 @@ use yew::{
/// Trait that allows you to use `ComponentLink` and `AgentLink` to register futures.
pub trait LinkFuture {
type Message;
/// This method creates a `Callback` which returns a Future which
/// returns a message to be sent back to the component's event
/// loop.
///
/// # Panics
/// If the future panics, then the promise will not resolve, and
/// will leak.
fn callback_future<FN, FU, IN, M>(&self, function: FN) -> yew::Callback<IN>
where
M: Into<Self::Message>,
FU: Future<Output = M> + 'static,
FN: Fn(IN) -> FU + 'static;
/// This method processes a Future that returns a message and sends it back to the component's
/// loop.
///
/// # Panics
/// If the future panics, then the promise will not resolve, and will leak.
fn send_future<F>(&self, future: F)
fn send_future<F, M>(&self, future: F)
where
F: Future<Output = Self::Message> + 'static;
M: Into<Self::Message>,
F: Future<Output = M> + 'static;
/// Registers a future that resolves to multiple messages.
/// # Panics
@ -28,13 +43,30 @@ pub trait LinkFuture {
impl<COMP: Component> LinkFuture for ComponentLink<COMP> {
type Message = COMP::Message;
fn send_future<F>(&self, future: F)
fn callback_future<FN, FU, IN, M>(&self, function: FN) -> yew::Callback<IN>
where
F: Future<Output = Self::Message> + 'static,
M: Into<Self::Message>,
FU: Future<Output = M> + 'static,
FN: Fn(IN) -> FU + 'static,
{
let link = self.clone();
let closure = move |input: IN| {
let future: FU = function(input);
link.send_future(future);
};
closure.into()
}
fn send_future<F, M>(&self, future: F)
where
M: Into<Self::Message>,
F: Future<Output = M> + 'static,
{
let link: ComponentLink<COMP> = self.clone();
let js_future = async move {
let message: COMP::Message = future.await;
let message: COMP::Message = future.await.into();
link.send_message(message);
};
spawn_local(js_future);
@ -56,13 +88,30 @@ impl<COMP: Component> LinkFuture for ComponentLink<COMP> {
impl<AGN: Agent> LinkFuture for AgentLink<AGN> {
type Message = AGN::Message;
fn send_future<F>(&self, future: F)
fn callback_future<FN, FU, IN, M>(&self, function: FN) -> yew::Callback<IN>
where
F: Future<Output = Self::Message> + 'static,
M: Into<Self::Message>,
FU: Future<Output = M> + 'static,
FN: Fn(IN) -> FU + 'static,
{
let link = self.clone();
let closure = move |input: IN| {
let future: FU = function(input);
link.send_future(future);
};
closure.into()
}
fn send_future<F, M>(&self, future: F)
where
M: Into<Self::Message>,
F: Future<Output = M> + 'static,
{
let link: AgentLink<AGN> = self.clone();
let js_future = async move {
let message: AGN::Message = future.await;
let message: AGN::Message = future.await.into();
let cb = link.callback(|m: AGN::Message| m);
cb.emit(message);
};