conch_runtime_pshaw/env/
last_status.rs

1use crate::env::SubEnvironment;
2use crate::{ExitStatus, EXIT_SUCCESS};
3
4/// An interface for setting and getting the
5/// exit status of the last command to run.
6pub trait LastStatusEnvironment {
7    /// Get the exit status of the previous command.
8    fn last_status(&self) -> ExitStatus;
9    /// Set the exit status of the previously run command.
10    fn set_last_status(&mut self, status: ExitStatus);
11}
12
13impl<'a, T: ?Sized + LastStatusEnvironment> LastStatusEnvironment for &'a mut T {
14    fn last_status(&self) -> ExitStatus {
15        (**self).last_status()
16    }
17
18    fn set_last_status(&mut self, status: ExitStatus) {
19        (**self).set_last_status(status);
20    }
21}
22
23/// An environment module for setting and getting
24/// the exit status of the last command to run.
25#[derive(Debug, PartialEq, Eq, Clone, Copy)]
26pub struct LastStatusEnv {
27    /// The exit status of the last command that was executed.
28    last_status: ExitStatus,
29}
30
31impl LastStatusEnv {
32    /// Initializes a new `LastStatusEnv` with a successful last status.
33    pub fn new() -> Self {
34        Self::with_status(EXIT_SUCCESS)
35    }
36
37    /// Creates a new `LastStatusEnv` with a provided last status.
38    pub fn with_status(status: ExitStatus) -> Self {
39        LastStatusEnv {
40            last_status: status,
41        }
42    }
43}
44
45impl LastStatusEnvironment for LastStatusEnv {
46    fn last_status(&self) -> ExitStatus {
47        self.last_status
48    }
49
50    fn set_last_status(&mut self, status: ExitStatus) {
51        self.last_status = status;
52    }
53}
54
55impl Default for LastStatusEnv {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61impl SubEnvironment for LastStatusEnv {
62    fn sub_env(&self) -> Self {
63        *self
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use crate::env::SubEnvironment;
71    use crate::ExitStatus;
72
73    #[test]
74    fn test_env_set_and_get_last_status() {
75        let exit = ExitStatus::Signal(9);
76        let mut env = LastStatusEnv::new();
77        env.set_last_status(exit);
78        assert_eq!(env.last_status(), exit);
79    }
80
81    #[test]
82    fn test_set_last_status_in_child_env_should_not_affect_parent() {
83        let parent_exit = ExitStatus::Signal(9);
84        let mut parent = LastStatusEnv::new();
85        parent.set_last_status(parent_exit);
86
87        {
88            let child_exit = ExitStatus::Code(42);
89            let mut child = parent.sub_env();
90            assert_eq!(child.last_status(), parent_exit);
91
92            child.set_last_status(child_exit);
93            assert_eq!(child.last_status(), child_exit);
94
95            assert_eq!(parent.last_status(), parent_exit);
96        }
97
98        assert_eq!(parent.last_status(), parent_exit);
99    }
100}