command_engine/shared/command.rs
1use super::*;
2
3/// Each type implementing `Command` trait must also implement `CommandInfo` which is used only to
4/// retrieve information about the Command.
5pub trait CommandInfo {
6 fn caller(&self) -> &'static str;
7}
8
9#[cfg(feature = "async")]
10mod command_async {
11 use super::*;
12 use std::future::Future;
13 use std::pin::Pin;
14 use std::task::{Context, Poll};
15
16 /// Example:
17 /// ```rust
18 /// use command_engine::{Command, CommandInfo, Instruction, OutputFuture, IntoOutputFuture};
19 ///
20 /// struct MyCommand1;
21 ///
22 /// impl CommandInfo for MyCommand1 {
23 /// fn caller(&self) -> &'static str {
24 /// "command1"
25 /// }
26 /// }
27 ///
28 /// impl Command for MyCommand1 {
29 /// type Output = ();
30 ///
31 /// fn on_execute<'a>(&self, _ins: Instruction<'a>) -> OutputFuture<'a, Self::Output> {
32 /// async move {
33 /// ()
34 /// }.output_future()
35 /// }
36 /// }
37 /// ```
38 pub trait Command: CommandInfo + Send + Sync + 'static {
39 type Output;
40
41 fn on_execute<'a>(&self, ins: Instruction<'a>) -> OutputFuture<'a, Self::Output>;
42 }
43
44 pub struct OutputFuture<'a, Output> {
45 future: Pin<Box<dyn Future<Output=Output> + Send + 'a>>,
46 }
47
48 impl<'a, Output> Future for OutputFuture<'a, Output> {
49 type Output = Output;
50
51 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
52 self.future.as_mut().poll(cx)
53 }
54 }
55
56 pub trait IntoOutputFuture<'a, Output> {
57 fn output_future(self) -> OutputFuture<'a, Output>;
58 }
59
60 impl<'a, F: Future<Output=Output> + Send + 'a, Output> IntoOutputFuture<'a, Output> for F {
61 fn output_future(self) -> OutputFuture<'a, Output> {
62 OutputFuture {
63 future: Box::pin(self),
64 }
65 }
66 }
67}
68
69#[cfg(not(feature = "async"))]
70mod command_sync {
71 use super::*;
72
73 /// Example:
74 /// ```rust
75 /// use command_engine::{Command, CommandInfo, Instruction};
76 ///
77 /// struct MyCommand1;
78 ///
79 /// impl CommandInfo for MyCommand1 {
80 /// fn caller(&self) -> &'static str {
81 /// "command1"
82 /// }
83 /// }
84 ///
85 /// impl Command for MyCommand1 {
86 /// type Output = ();
87 ///
88 /// fn on_execute(&self, _ins: Instruction) -> Self::Output {
89 /// ()
90 /// }
91 /// }
92 /// ```
93 pub trait Command: CommandInfo + 'static {
94 type Output;
95
96 fn on_execute(&self, ins: Instruction) -> Self::Output;
97 }
98}
99
100#[cfg(feature = "async")]
101pub use command_async::*;
102
103#[cfg(not(feature = "async"))]
104pub use command_sync::*;
105