Skip to content

Commit

Permalink
Introduce MaybeSend trait in iced_futures
Browse files Browse the repository at this point in the history
It allows to clean up all the `trait_aliases` modules!
  • Loading branch information
hecrj committed Jan 28, 2022
1 parent 83c649b commit 5dab5a3
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 150 deletions.
8 changes: 2 additions & 6 deletions futures/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub use self::smol::Smol;
#[cfg(target_arch = "wasm32")]
pub use wasm_bindgen::WasmBindgen;

use crate::MaybeSend;
use futures::Future;

/// A type that can run futures.
Expand All @@ -43,12 +44,7 @@ pub trait Executor: Sized {
Self: Sized;

/// Spawns a future in the [`Executor`].
#[cfg(not(target_arch = "wasm32"))]
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static);

/// Spawns a local future in the [`Executor`].
#[cfg(target_arch = "wasm32")]
fn spawn(&self, future: impl Future<Output = ()> + 'static);
fn spawn(&self, future: impl Future<Output = ()> + MaybeSend + 'static);

/// Runs the given closure inside the [`Executor`].
///
Expand Down
2 changes: 2 additions & 0 deletions futures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
pub use futures;

mod command;
mod maybe_send;
mod runtime;

pub mod executor;
Expand All @@ -35,6 +36,7 @@ pub mod time;

pub use command::Command;
pub use executor::Executor;
pub use maybe_send::MaybeSend;
pub use platform::*;
pub use runtime::Runtime;
pub use subscription::Subscription;
Expand Down
21 changes: 21 additions & 0 deletions futures/src/maybe_send.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#[cfg(not(target_arch = "wasm32"))]
mod platform {
/// An extension trait that enforces `Send` only on native platforms.
///
/// Useful to write cross-platform async code!
pub trait MaybeSend: Send {}

impl<T> MaybeSend for T where T: Send {}
}

#[cfg(target_arch = "wasm32")]
mod platform {
/// An extension trait that enforces `Send` only on native platforms.
///
/// Useful to write cross-platform async code!
pub trait MaybeSend {}

impl<T> MaybeSend for T {}
}

pub use platform::MaybeSend;
56 changes: 8 additions & 48 deletions futures/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,10 @@
//! Run commands and keep track of subscriptions.
use crate::BoxFuture;
use crate::{subscription, Executor, Subscription};
use crate::subscription;
use crate::{BoxFuture, Executor, MaybeSend, Subscription};

use futures::{channel::mpsc, Sink};
use std::marker::PhantomData;

#[cfg(not(target_arch = "wasm32"))]
mod trait_aliases {
use super::*;

pub trait RuntimeMessage: Send + 'static {}

impl<T> RuntimeMessage for T where T: Send + 'static {}

pub trait RuntimeMessageSender<Message: RuntimeMessage>:
Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static
{
}

impl<Message: RuntimeMessage, T> RuntimeMessageSender<Message> for T where
T: Sink<Message, Error = mpsc::SendError>
+ Unpin
+ Send
+ Clone
+ 'static
{
}
}

#[cfg(target_arch = "wasm32")]
mod trait_aliases {
use super::*;

pub trait RuntimeMessage: 'static {}

impl<T> RuntimeMessage for T where T: 'static {}

pub trait RuntimeMessageSender<Message: RuntimeMessage>:
Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
{
}

impl<Message: RuntimeMessage, T> RuntimeMessageSender<Message> for T where
T: Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
{
}
}

pub use trait_aliases::{RuntimeMessage, RuntimeMessageSender};

/// A batteries-included runtime of commands and subscriptions.
///
/// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any
Expand All @@ -67,8 +23,12 @@ where
Hasher: std::hash::Hasher + Default,
Event: Send + Clone + 'static,
Executor: self::Executor,
Sender: RuntimeMessageSender<Message>,
Message: RuntimeMessage,
Sender: Sink<Message, Error = mpsc::SendError>
+ Unpin
+ MaybeSend
+ Clone
+ 'static,
Message: MaybeSend + 'static,
{
/// Creates a new empty [`Runtime`].
///
Expand Down
54 changes: 7 additions & 47 deletions futures/src/subscription/tracker.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,8 @@
use crate::{BoxFuture, Subscription};
use crate::{BoxFuture, MaybeSend, Subscription};

use futures::{channel::mpsc, sink::Sink};
use std::{collections::HashMap, marker::PhantomData};

#[cfg(not(target_arch = "wasm32"))]
mod trait_aliases {
use super::*;

pub trait TrackerMessage: Send + 'static {}

impl<T> TrackerMessage for T where T: Send + 'static {}

pub trait TrackerMessageReceiver<Message: TrackerMessage>:
Sink<Message, Error = mpsc::SendError> + Unpin + Send + Clone + 'static
{
}

impl<Message: TrackerMessage, T> TrackerMessageReceiver<Message> for T where
T: Sink<Message, Error = mpsc::SendError>
+ Unpin
+ Send
+ Clone
+ 'static
{
}
}

#[cfg(target_arch = "wasm32")]
mod trait_aliases {
use super::*;

pub trait TrackerMessage: 'static {}

impl<T> TrackerMessage for T where T: 'static {}

pub trait TrackerMessageReceiver<Message: TrackerMessage>:
Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
{
}

impl<Message: TrackerMessage, T> TrackerMessageReceiver<Message> for T where
T: Sink<Message, Error = mpsc::SendError> + Unpin + Clone + 'static
{
}
}

pub use trait_aliases::{TrackerMessage, TrackerMessageReceiver};

/// A registry of subscription streams.
///
/// If you have an application that continuously returns a [`Subscription`],
Expand Down Expand Up @@ -101,8 +57,12 @@ where
receiver: Receiver,
) -> Vec<BoxFuture<()>>
where
Message: TrackerMessage,
Receiver: TrackerMessageReceiver<Message>,
Message: 'static + MaybeSend,
Receiver: 'static
+ Sink<Message, Error = mpsc::SendError>
+ Unpin
+ MaybeSend
+ Clone,
{
use futures::{future::FutureExt, stream::StreamExt};

Expand Down
58 changes: 9 additions & 49 deletions native/src/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,10 @@ use crate::event::{self, Event};
use crate::Hasher;

use iced_futures::futures::{self, Future, Stream};
use iced_futures::BoxStream;
use iced_futures::{BoxStream, MaybeSend};

use std::hash::Hash;

#[cfg(not(target_arch = "wasm32"))]
mod trait_aliases {
use super::*;

/// Wrapper type
pub trait RunnerStream<Message>:
Stream<Item = Message> + Send + 'static
{
}

impl<T, Message> RunnerStream<Message> for T where
T: Stream<Item = Message> + Send + 'static
{
}
}

#[cfg(target_arch = "wasm32")]
mod trait_aliases {
use super::*;

/// Wrapper type
pub trait RunnerStream<Message>: Stream<Item = Message> + 'static {}

impl<T, Message> RunnerStream<Message> for T where
T: Stream<Item = Message> + 'static
{
}
}

pub use trait_aliases::RunnerStream;

/// A request to listen to external events.
///
/// Besides performing async actions on demand with [`Command`], most
Expand Down Expand Up @@ -87,7 +56,7 @@ pub fn events_with<Message>(
f: fn(Event, event::Status) -> Option<Message>,
) -> Subscription<Message>
where
Message: 'static + Send,
Message: 'static + MaybeSend,
{
Subscription::from_recipe(Runner {
id: f,
Expand All @@ -109,7 +78,7 @@ where
pub fn run<I, S, Message>(id: I, stream: S) -> Subscription<Message>
where
I: Hash + 'static,
S: Stream<Item = Message> + Send + 'static,
S: Stream<Item = Message> + MaybeSend + 'static,
Message: 'static,
{
Subscription::from_recipe(Runner {
Expand Down Expand Up @@ -190,13 +159,13 @@ where
pub fn unfold<I, T, Fut, Message>(
id: I,
initial: T,
mut f: impl FnMut(T) -> Fut + Send + Sync + 'static,
mut f: impl FnMut(T) -> Fut + MaybeSend + Sync + 'static,
) -> Subscription<Message>
where
I: Hash + 'static,
T: Send + 'static,
Fut: Future<Output = (Option<Message>, T)> + Send + 'static,
Message: 'static + Send,
T: MaybeSend + 'static,
Fut: Future<Output = (Option<Message>, T)> + MaybeSend + 'static,
Message: 'static + MaybeSend,
{
use futures::future::{self, FutureExt};
use futures::stream::StreamExt;
Expand All @@ -222,7 +191,7 @@ impl<I, S, F, Message> Recipe<Hasher, (Event, event::Status)>
where
I: Hash + 'static,
F: FnOnce(EventStream) -> S,
S: RunnerStream<Message>,
S: Stream<Item = Message> + MaybeSend + 'static,
{
type Output = Message;

Expand All @@ -232,15 +201,6 @@ where
}

fn stream(self: Box<Self>, input: EventStream) -> BoxStream<Self::Output> {
use futures::stream::StreamExt;

#[cfg(target_arch = "wasm32")]
{
(self.spawn)(input).boxed_local()
}
#[cfg(not(target_arch = "wasm32"))]
{
(self.spawn)(input).boxed()
}
iced_futures::boxed_stream((self.spawn)(input))
}
}

0 comments on commit 5dab5a3

Please sign in to comment.