putzen_cli/caches/tui/
command.rs1#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct Command<E, M> {
9 pub events: Vec<M>,
10 pub effects: Vec<E>,
11}
12
13impl<E, M> Command<E, M> {
14 pub fn done() -> Self {
15 Self {
16 events: Vec::new(),
17 effects: Vec::new(),
18 }
19 }
20
21 pub fn event(m: M) -> Self {
22 Self {
23 events: vec![m],
24 effects: Vec::new(),
25 }
26 }
27
28 pub fn effect(e: E) -> Self {
29 Self {
30 events: Vec::new(),
31 effects: vec![e],
32 }
33 }
34
35 pub fn batch<I: IntoIterator<Item = Self>>(cmds: I) -> Self {
36 let mut out = Self::done();
37 for c in cmds {
38 out.events.extend(c.events);
39 out.effects.extend(c.effects);
40 }
41 out
42 }
43
44 pub fn and(mut self, other: Self) -> Self {
45 self.events.extend(other.events);
46 self.effects.extend(other.effects);
47 self
48 }
49
50 pub fn is_done(&self) -> bool {
51 self.events.is_empty() && self.effects.is_empty()
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[derive(Debug, PartialEq, Eq, Clone)]
60 enum E {
61 A,
62 B,
63 }
64 #[derive(Debug, PartialEq, Eq, Clone)]
65 enum M {
66 X,
67 Y,
68 }
69
70 #[test]
71 fn done_is_empty() {
72 let c: Command<E, M> = Command::done();
73 assert!(c.is_done());
74 }
75
76 #[test]
77 fn event_carries_only_msg() {
78 let c: Command<E, M> = Command::event(M::X);
79 assert_eq!(c.events, vec![M::X]);
80 assert!(c.effects.is_empty());
81 assert!(!c.is_done());
82 }
83
84 #[test]
85 fn effect_carries_only_effect() {
86 let c: Command<E, M> = Command::effect(E::A);
87 assert!(c.events.is_empty());
88 assert_eq!(c.effects, vec![E::A]);
89 }
90
91 #[test]
92 fn and_concatenates_in_order() {
93 let c: Command<E, M> = Command::event(M::X).and(Command::effect(E::A));
94 assert_eq!(c.events, vec![M::X]);
95 assert_eq!(c.effects, vec![E::A]);
96
97 let d: Command<E, M> = Command::effect(E::B).and(Command::event(M::Y));
98 assert_eq!(d.events, vec![M::Y]);
99 assert_eq!(d.effects, vec![E::B]);
100 }
101
102 #[test]
103 fn batch_concatenates_all() {
104 let c: Command<E, M> = Command::batch([
105 Command::event(M::X),
106 Command::effect(E::A),
107 Command::event(M::Y),
108 Command::effect(E::B),
109 ]);
110 assert_eq!(c.events, vec![M::X, M::Y]);
111 assert_eq!(c.effects, vec![E::A, E::B]);
112 }
113
114 #[test]
115 fn batch_of_empty_is_done() {
116 let c: Command<E, M> = Command::batch(std::iter::empty());
117 assert!(c.is_done());
118 }
119}