summaryrefslogtreecommitdiffstats
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/command.rs100
-rw-r--r--core/src/lib.rs12
-rw-r--r--core/src/subscription.rs183
3 files changed, 0 insertions, 295 deletions
diff --git a/core/src/command.rs b/core/src/command.rs
deleted file mode 100644
index e7885fb8..00000000
--- a/core/src/command.rs
+++ /dev/null
@@ -1,100 +0,0 @@
-use futures::future::{BoxFuture, Future, FutureExt};
-
-/// A collection of async operations.
-///
-/// You should be able to turn a future easily into a [`Command`], either by
-/// using the `From` trait or [`Command::perform`].
-///
-/// [`Command`]: struct.Command.html
-pub struct Command<T> {
- futures: Vec<BoxFuture<'static, T>>,
-}
-
-impl<T> Command<T> {
- /// Creates an empty [`Command`].
- ///
- /// In other words, a [`Command`] that does nothing.
- ///
- /// [`Command`]: struct.Command.html
- pub fn none() -> Self {
- Self {
- futures: Vec::new(),
- }
- }
-
- /// Creates a [`Command`] that performs the action of the given future.
- ///
- /// [`Command`]: struct.Command.html
- pub fn perform<A>(
- future: impl Future<Output = T> + 'static + Send,
- f: impl Fn(T) -> A + 'static + Send,
- ) -> Command<A> {
- Command {
- futures: vec![future.map(f).boxed()],
- }
- }
-
- /// Applies a transformation to the result of a [`Command`].
- ///
- /// [`Command`]: struct.Command.html
- pub fn map<A>(
- mut self,
- f: impl Fn(T) -> A + 'static + Send + Sync,
- ) -> Command<A>
- where
- T: 'static,
- {
- let f = std::sync::Arc::new(f);
-
- Command {
- futures: self
- .futures
- .drain(..)
- .map(|future| {
- let f = f.clone();
-
- future.map(move |result| f(result)).boxed()
- })
- .collect(),
- }
- }
-
- /// Creates a [`Command`] that performs the actions of all the given
- /// commands.
- ///
- /// Once this command is run, all the commands will be exectued at once.
- ///
- /// [`Command`]: struct.Command.html
- pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self {
- Self {
- futures: commands
- .into_iter()
- .flat_map(|command| command.futures)
- .collect(),
- }
- }
-
- /// Converts a [`Command`] into its underlying list of futures.
- ///
- /// [`Command`]: struct.Command.html
- pub fn futures(self) -> Vec<BoxFuture<'static, T>> {
- self.futures
- }
-}
-
-impl<T, A> From<A> for Command<T>
-where
- A: Future<Output = T> + 'static + Send,
-{
- fn from(future: A) -> Self {
- Self {
- futures: vec![future.boxed()],
- }
- }
-}
-
-impl<T> std::fmt::Debug for Command<T> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("Command").finish()
- }
-}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 821b09c1..51863327 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -32,15 +32,3 @@ pub use length::Length;
pub use point::Point;
pub use rectangle::Rectangle;
pub use vector::Vector;
-
-#[cfg(feature = "command")]
-mod command;
-
-#[cfg(feature = "command")]
-pub use command::Command;
-
-#[cfg(feature = "subscription")]
-pub mod subscription;
-
-#[cfg(feature = "subscription")]
-pub use subscription::Subscription;
diff --git a/core/src/subscription.rs b/core/src/subscription.rs
deleted file mode 100644
index d9e7e388..00000000
--- a/core/src/subscription.rs
+++ /dev/null
@@ -1,183 +0,0 @@
-//! Listen to external events in your application.
-
-/// A request to listen to external events.
-///
-/// Besides performing async actions on demand with [`Command`], most
-/// applications also need to listen to external events passively.
-///
-/// A [`Subscription`] is normally provided to some runtime, like a [`Command`],
-/// and it will generate events as long as the user keeps requesting it.
-///
-/// For instance, you can use a [`Subscription`] to listen to a WebSocket
-/// connection, keyboard presses, mouse events, time ticks, etc.
-///
-/// This type is normally aliased by runtimes with a specific `Input` and/or
-/// `Hasher`.
-///
-/// [`Command`]: ../struct.Command.html
-/// [`Subscription`]: struct.Subscription.html
-pub struct Subscription<Hasher, Input, Output> {
- recipes: Vec<Box<dyn Recipe<Hasher, Input, Output = Output>>>,
-}
-
-impl<H, I, O> Subscription<H, I, O>
-where
- H: std::hash::Hasher,
-{
- /// Returns an empty [`Subscription`] that will not produce any output.
- ///
- /// [`Subscription`]: struct.Subscription.html
- pub fn none() -> Self {
- Self {
- recipes: Vec::new(),
- }
- }
-
- /// Creates a [`Subscription`] from a [`Recipe`] describing it.
- ///
- /// [`Subscription`]: struct.Subscription.html
- /// [`Recipe`]: trait.Recipe.html
- pub fn from_recipe(
- recipe: impl Recipe<H, I, Output = O> + 'static,
- ) -> Self {
- Self {
- recipes: vec![Box::new(recipe)],
- }
- }
-
- /// Batches all the provided subscriptions and returns the resulting
- /// [`Subscription`].
- ///
- /// [`Subscription`]: struct.Subscription.html
- pub fn batch(
- subscriptions: impl IntoIterator<Item = Subscription<H, I, O>>,
- ) -> Self {
- Self {
- recipes: subscriptions
- .into_iter()
- .flat_map(|subscription| subscription.recipes)
- .collect(),
- }
- }
-
- /// Returns the different recipes of the [`Subscription`].
- ///
- /// [`Subscription`]: struct.Subscription.html
- pub fn recipes(self) -> Vec<Box<dyn Recipe<H, I, Output = O>>> {
- self.recipes
- }
-
- /// Transforms the [`Subscription`] output with the given function.
- ///
- /// [`Subscription`]: struct.Subscription.html
- pub fn map<A>(
- mut self,
- f: impl Fn(O) -> A + Send + Sync + 'static,
- ) -> Subscription<H, I, A>
- where
- H: 'static,
- I: 'static,
- O: 'static,
- A: 'static,
- {
- let function = std::sync::Arc::new(f);
-
- Subscription {
- recipes: self
- .recipes
- .drain(..)
- .map(|recipe| {
- Box::new(Map::new(recipe, function.clone()))
- as Box<dyn Recipe<H, I, Output = A>>
- })
- .collect(),
- }
- }
-}
-
-impl<I, O, H> std::fmt::Debug for Subscription<I, O, H> {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("Subscription").finish()
- }
-}
-
-/// The description of a [`Subscription`].
-///
-/// A [`Recipe`] is the internal definition of a [`Subscription`]. It is used
-/// by runtimes to run and identify subscriptions. You can use it to create your
-/// own!
-///
-/// [`Subscription`]: struct.Subscription.html
-/// [`Recipe`]: trait.Recipe.html
-pub trait Recipe<Hasher: std::hash::Hasher, Input> {
- /// The events that will be produced by a [`Subscription`] with this
- /// [`Recipe`].
- ///
- /// [`Subscription`]: struct.Subscription.html
- /// [`Recipe`]: trait.Recipe.html
- type Output;
-
- /// Hashes the [`Recipe`].
- ///
- /// This is used by runtimes to uniquely identify a [`Subscription`].
- ///
- /// [`Subscription`]: struct.Subscription.html
- /// [`Recipe`]: trait.Recipe.html
- fn hash(&self, state: &mut Hasher);
-
- /// Executes the [`Recipe`] and produces the stream of events of its
- /// [`Subscription`].
- ///
- /// It receives some generic `Input`, which is normally defined by runtimes.
- ///
- /// [`Subscription`]: struct.Subscription.html
- /// [`Recipe`]: trait.Recipe.html
- fn stream(
- self: Box<Self>,
- input: Input,
- ) -> futures::stream::BoxStream<'static, Self::Output>;
-}
-
-struct Map<Hasher, Input, A, B> {
- recipe: Box<dyn Recipe<Hasher, Input, Output = A>>,
- mapper: std::sync::Arc<dyn Fn(A) -> B + Send + Sync>,
-}
-
-impl<H, I, A, B> Map<H, I, A, B> {
- fn new(
- recipe: Box<dyn Recipe<H, I, Output = A>>,
- mapper: std::sync::Arc<dyn Fn(A) -> B + Send + Sync + 'static>,
- ) -> Self {
- Map { recipe, mapper }
- }
-}
-
-impl<H, I, A, B> Recipe<H, I> for Map<H, I, A, B>
-where
- A: 'static,
- B: 'static,
- H: std::hash::Hasher,
-{
- type Output = B;
-
- fn hash(&self, state: &mut H) {
- use std::hash::Hash;
-
- std::any::TypeId::of::<B>().hash(state);
- self.recipe.hash(state);
- }
-
- fn stream(
- self: Box<Self>,
- input: I,
- ) -> futures::stream::BoxStream<'static, Self::Output> {
- use futures::StreamExt;
-
- let mapper = self.mapper;
-
- self.recipe
- .stream(input)
- .map(move |element| mapper(element))
- .boxed()
- }
-}