use std::future::Future;
use std::pin::Pin;
pub struct Command<M> {
pub(crate) kind: CommandKind<M>,
}
pub(crate) enum CommandKind<M> {
None,
Quit,
Batch(Vec<Command<M>>),
#[allow(dead_code)]
Task(Pin<Box<dyn Future<Output = M> + Send + 'static>>),
Message(M),
}
impl<M> Command<M> {
#[must_use]
pub fn none() -> Self {
Self {
kind: CommandKind::None,
}
}
#[must_use]
pub fn quit() -> Self {
Self {
kind: CommandKind::Quit,
}
}
#[must_use]
pub fn message(msg: M) -> Self {
Self {
kind: CommandKind::Message(msg),
}
}
#[must_use]
pub fn batch(commands: Vec<Command<M>>) -> Self {
Self {
kind: CommandKind::Batch(commands),
}
}
pub fn perform<F, Fut>(task: F) -> Self
where
F: FnOnce() -> Fut,
Fut: Future<Output = M> + Send + 'static,
M: Send + 'static,
{
Self {
kind: CommandKind::Task(Box::pin(task())),
}
}
#[must_use]
pub fn is_quit(&self) -> bool {
matches!(self.kind, CommandKind::Quit)
}
#[must_use]
pub fn is_none(&self) -> bool {
matches!(self.kind, CommandKind::None)
}
}
impl<M> Default for Command<M> {
fn default() -> Self {
Self::none()
}
}
pub type Cmd<M> = Command<M>;