beetry_node/decorator/
invert.rs1use beetry_core::{Node, TickStatus};
2
3pub struct Invert<N> {
5 node: N,
6}
7
8impl<N> Invert<N> {
9 #[must_use]
10 pub fn new(node: N) -> Self {
11 Self { node }
12 }
13}
14
15impl<N> Node for Invert<N>
16where
17 N: Node,
18{
19 fn tick(&mut self) -> TickStatus {
20 match self.node.tick() {
21 TickStatus::Success => TickStatus::Failure,
22 TickStatus::Failure => TickStatus::Success,
23 TickStatus::Running => TickStatus::Running,
24 }
25 }
26
27 fn abort(&mut self) {
28 self.node.abort();
29 }
30
31 fn reset(&mut self) {
32 self.node.reset();
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use beetry_core::{Node, TickStatus};
39
40 use super::*;
41 use crate::mock_test::mock_returns;
42
43 #[test]
44 fn success_becomes_failure() {
45 let mut invert = Invert::new(mock_returns([TickStatus::Success]));
46 assert_eq!(invert.tick(), TickStatus::Failure);
47 }
48
49 #[test]
50 fn failure_becomes_success() {
51 let mut invert = Invert::new(mock_returns([TickStatus::Failure]));
52 assert_eq!(invert.tick(), TickStatus::Success);
53 }
54
55 #[test]
56 fn running_stays_running() {
57 let mut invert = Invert::new(mock_returns([TickStatus::Running]));
58 assert_eq!(invert.tick(), TickStatus::Running);
59 }
60
61 #[test]
62 fn abort_is_propagated() {
63 let mut node = mock_returns([]);
64 node.expect_abort().once().return_const(());
65 let mut invert = Invert::new(node);
66 invert.abort();
67 }
68
69 #[test]
70 fn reset_is_propagated() {
71 let mut node = mock_returns([]);
72 node.expect_reset().once().return_const(());
73 let mut invert = Invert::new(node);
74 invert.reset();
75 }
76}