diff options
-rw-r--r-- | futures/src/command.rs | 69 | ||||
-rw-r--r-- | futures/src/lib.rs | 2 | ||||
-rw-r--r-- | native/src/command.rs | 65 | ||||
-rw-r--r-- | web/src/command.rs | 65 | ||||
-rw-r--r-- | winit/src/clipboard.rs | 4 |
5 files changed, 123 insertions, 82 deletions
diff --git a/futures/src/command.rs b/futures/src/command.rs new file mode 100644 index 00000000..d8adfe49 --- /dev/null +++ b/futures/src/command.rs @@ -0,0 +1,69 @@ +/// A set of asynchronous actions to be performed by some runtime. +#[derive(Debug)] +pub struct Command<T>(Internal<T>); + +#[derive(Debug)] +enum Internal<T> { + None, + Single(T), + Batch(Vec<T>), +} + +impl<T> Command<T> { + /// Creates an empty [`Command`]. + /// + /// In other words, a [`Command`] that does nothing. + pub const fn none() -> Self { + Self(Internal::None) + } + + /// Creates a [`Command`] that performs a single [`Action`]. + pub const fn single(action: T) -> Self { + Self(Internal::Single(action)) + } + + /// Creates a [`Command`] that performs the actions of all the given + /// commands. + /// + /// Once this command is run, all the commands will be executed at once. + pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self { + let mut batch = Vec::new(); + + for Command(command) in commands { + match command { + Internal::None => {} + Internal::Single(command) => batch.push(command), + Internal::Batch(commands) => batch.extend(commands), + } + } + + Self(Internal::Batch(batch)) + } + + /// Applies a transformation to the result of a [`Command`]. + pub fn map<A>(self, f: impl Fn(T) -> A) -> Command<A> + where + T: 'static, + { + let Command(command) = self; + + match command { + Internal::None => Command::none(), + Internal::Single(action) => Command::single(f(action)), + Internal::Batch(batch) => { + Command(Internal::Batch(batch.into_iter().map(f).collect())) + } + } + } + + /// Returns all of the actions of the [`Command`]. + pub fn actions(self) -> Vec<T> { + let Command(command) = self; + + match command { + Internal::None => Vec::new(), + Internal::Single(action) => vec![action], + Internal::Batch(batch) => batch, + } + } +} diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 657aab37..01cf5c89 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -10,6 +10,7 @@ pub use futures; +mod command; mod runtime; pub mod executor; @@ -34,6 +35,7 @@ pub mod subscription; )] pub mod time; +pub use command::Command; pub use executor::Executor; pub use runtime::Runtime; pub use subscription::Subscription; diff --git a/native/src/command.rs b/native/src/command.rs index 16fd73ba..1d41539b 100644 --- a/native/src/command.rs +++ b/native/src/command.rs @@ -5,18 +5,19 @@ pub use action::Action; use std::future::Future; /// A set of asynchronous actions to be performed by some runtime. -pub enum Command<T> { - None, - Single(Action<T>), - Batch(Vec<Action<T>>), -} +pub struct Command<T>(iced_futures::Command<Action<T>>); impl<T> Command<T> { /// Creates an empty [`Command`]. /// /// In other words, a [`Command`] that does nothing. - pub fn none() -> Self { - Self::None + pub const fn none() -> Self { + Self(iced_futures::Command::none()) + } + + /// Creates a [`Command`] that performs a single [`Action`]. + pub const fn single(action: Action<T>) -> Self { + Self(iced_futures::Command::single(action)) } /// Creates a [`Command`] that performs the action of the given future. @@ -26,7 +27,17 @@ impl<T> Command<T> { ) -> Command<A> { use iced_futures::futures::FutureExt; - Command::Single(Action::Future(Box::pin(future.map(f)))) + Command::single(Action::Future(Box::pin(future.map(f)))) + } + + /// Creates a [`Command`] that performs the actions of all the given + /// commands. + /// + /// Once this command is run, all the commands will be executed at once. + pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self { + Self(iced_futures::Command::batch( + commands.into_iter().map(|Command(command)| command), + )) } /// Applies a transformation to the result of a [`Command`]. @@ -37,41 +48,15 @@ impl<T> Command<T> { where T: 'static, { - match self { - Self::None => Command::None, - Self::Single(action) => Command::Single(action.map(f)), - Self::Batch(batch) => Command::Batch( - batch - .into_iter() - .map(|action| action.map(f.clone())) - .collect(), - ), - } - } + let Command(command) = self; - /// Creates a [`Command`] that performs the actions of all the given - /// commands. - /// - /// Once this command is run, all the commands will be executed at once. - pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self { - let mut batch = Vec::new(); - - for command in commands { - match command { - Self::None => {} - Self::Single(command) => batch.push(command), - Self::Batch(commands) => batch.extend(commands), - } - } - - Self::Batch(batch) + Command(command.map(move |action| action.map(f.clone()))) } + /// Returns all of the actions of the [`Command`]. pub fn actions(self) -> Vec<Action<T>> { - match self { - Self::None => Vec::new(), - Self::Single(action) => vec![action], - Self::Batch(batch) => batch, - } + let Command(command) = self; + + command.actions() } } diff --git a/web/src/command.rs b/web/src/command.rs index ff6965c1..f222795d 100644 --- a/web/src/command.rs +++ b/web/src/command.rs @@ -6,18 +6,19 @@ pub use action::Action; use std::future::Future; /// A set of asynchronous actions to be performed by some runtime. -pub enum Command<T> { - None, - Single(Action<T>), - Batch(Vec<Action<T>>), -} +pub struct Command<T>(iced_futures::Command<Action<T>>); impl<T> Command<T> { /// Creates an empty [`Command`]. /// /// In other words, a [`Command`] that does nothing. - pub fn none() -> Self { - Self::None + pub const fn none() -> Self { + Self(iced_futures::Command::none()) + } + + /// Creates a [`Command`] that performs a single [`Action`]. + pub const fn single(action: Action<T>) -> Self { + Self(iced_futures::Command::single(action)) } /// Creates a [`Command`] that performs the action of the given future. @@ -28,25 +29,7 @@ impl<T> Command<T> { ) -> Command<A> { use iced_futures::futures::FutureExt; - Command::Single(Action::Future(Box::pin(future.map(f)))) - } - - /// Applies a transformation to the result of a [`Command`]. - #[cfg(target_arch = "wasm32")] - pub fn map<A>(self, f: impl Fn(T) -> A + 'static + Clone) -> Command<A> - where - T: 'static, - { - match self { - Self::None => Command::None, - Self::Single(action) => Command::Single(action.map(f)), - Self::Batch(batch) => Command::Batch( - batch - .into_iter() - .map(|action| action.map(f.clone())) - .collect(), - ), - } + Command::single(Action::Future(Box::pin(future.map(f)))) } /// Creates a [`Command`] that performs the actions of all the given @@ -54,24 +37,26 @@ impl<T> Command<T> { /// /// Once this command is run, all the commands will be executed at once. pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self { - let mut batch = Vec::new(); + Self(iced_futures::Command::batch( + commands.into_iter().map(|Command(command)| command), + )) + } - for command in commands { - match command { - Self::None => {} - Self::Single(command) => batch.push(command), - Self::Batch(commands) => batch.extend(commands), - } - } + /// Applies a transformation to the result of a [`Command`]. + #[cfg(target_arch = "wasm32")] + pub fn map<A>(self, f: impl Fn(T) -> A + 'static + Clone) -> Command<A> + where + T: 'static, + { + let Command(command) = self; - Self::Batch(batch) + Command(command.map(move |action| action.map(f.clone()))) } + /// Returns all of the actions of the [`Command`]. pub fn actions(self) -> Vec<Action<T>> { - match self { - Self::None => Vec::new(), - Self::Single(action) => vec![action], - Self::Batch(batch) => batch, - } + let Command(command) = self; + + command.actions() } } diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 05d991ff..1b92b28d 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -62,10 +62,10 @@ impl iced_native::Clipboard for Clipboard { pub fn read<Message>( f: impl Fn(Option<String>) -> Message + 'static, ) -> Command<Message> { - Command::Single(command::Action::Clipboard(Action::Read(Box::new(f)))) + Command::single(command::Action::Clipboard(Action::Read(Box::new(f)))) } /// Write the given contents to the clipboard. pub fn write<Message>(contents: String) -> Command<Message> { - Command::Single(command::Action::Clipboard(Action::Write(contents))) + Command::single(command::Action::Clipboard(Action::Write(contents))) } |