1use crate::params::CollectedArgs;
2use crate::prelude::CliError;
3use crate::State;
4
5pub struct _Sync;
7pub struct _Async;
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
12pub struct SetState<S: Clone + Send + Sync + 'static>(pub S);
13
14pub trait HandlerEffect {
16 fn apply_effect(self, args: &mut CollectedArgs);
17}
18
19impl HandlerEffect for () {
20 fn apply_effect(self, _args: &mut CollectedArgs) {}
21}
22
23impl<S> HandlerEffect for SetState<S>
24where
25 S: Clone + Send + Sync + 'static,
26{
27 fn apply_effect(self, args: &mut CollectedArgs) {
28 args.insert(State(self.0), true)
29 }
30}
31
32#[async_trait::async_trait]
34pub trait IntoEffect<Type> {
35 type Effect: HandlerEffect;
36
37 async fn into_effect(self) -> Result<Self::Effect, CliError>;
38}
39
40#[async_trait::async_trait]
41impl IntoEffect<_Sync> for () {
42 type Effect = ();
43
44 async fn into_effect(self) -> Result<(), CliError> {
45 Ok(())
46 }
47}
48
49#[async_trait::async_trait]
50impl<S> IntoEffect<_Sync> for State<S>
51where
52 S: Clone + Send + Sync + 'static,
53{
54 type Effect = SetState<S>;
55
56 async fn into_effect(self) -> Result<Self::Effect, CliError> {
57 Ok(SetState(self.0))
58 }
59}
60
61#[async_trait::async_trait]
62impl<S> IntoEffect<_Sync> for SetState<S>
63where
64 S: Clone + Send + Sync + 'static,
65{
66 type Effect = SetState<S>;
67
68 async fn into_effect(self) -> Result<Self::Effect, CliError> {
69 Ok(self)
70 }
71}
72
73#[async_trait::async_trait]
74impl<E, F> IntoEffect<_Sync> for Result<F, E>
75where
76 E: Into<CliError>,
77 F: IntoEffect<_Sync> + Send,
78 Self: Send,
79{
80 type Effect = F::Effect;
81
82 async fn into_effect(self) -> Result<Self::Effect, CliError> {
83 match self {
84 | Ok(f) => f.into_effect().await,
85 | Err(e) => Err(e.into()),
86 }
87 }
88}
89
90#[async_trait::async_trait]
93impl<T, Output> IntoEffect<_Async> for T
94where
95 T: std::future::Future<Output = Output> + Send,
96 Output: IntoEffect<_Sync> + Send,
97{
98 type Effect = Output::Effect;
99
100 async fn into_effect(self) -> Result<Self::Effect, CliError> {
101 self.await.into_effect().await
102 }
103}