ex_cli/git/
flags.rs

1use git2::Status;
2
3#[derive(Clone, Copy, Debug, PartialEq)]
4pub struct GitFlags {
5    pub everything: bool,
6    pub cached: bool,
7    pub added: bool,
8    pub modified: bool,
9    pub renamed: bool,
10    pub ignored: bool,
11    pub untracked: bool,
12}
13
14impl GitFlags {
15    pub fn new() -> Self {
16        Self {
17            everything: false,
18            cached: false,
19            added: false,
20            modified: false,
21            renamed: false,
22            ignored: false,
23            untracked: false,
24        }
25    }
26
27    pub fn with_everything(mut self, everything: bool) -> Self {
28        self.everything = everything;
29        self
30    }
31
32    pub fn with_cached(mut self, cached: bool) -> Self {
33        self.cached = cached;
34        self
35    }
36
37    pub fn with_added(mut self, added: bool) -> Self {
38        self.added = added;
39        self
40    }
41
42    pub fn with_modified(mut self, modified: bool) -> Self {
43        self.modified = modified;
44        self
45    }
46
47    pub fn with_renamed(mut self, renamed: bool) -> Self {
48        self.renamed = renamed;
49        self
50    }
51
52    pub fn with_ignored(mut self, ignored: bool) -> Self {
53        self.ignored = ignored;
54        self
55    }
56
57    pub fn with_untracked(mut self, untracked: bool) -> Self {
58        self.untracked = untracked;
59        self
60    }
61
62    pub fn test_allowed(&self, status: &Status) -> Option<Self> {
63        if self.is_allowed(status) {
64            let flags = Self::new()
65                .with_added(status.is_index_new())
66                .with_modified(status.is_index_modified() || status.is_wt_modified())
67                .with_renamed(status.is_index_renamed() || status.is_wt_renamed())
68                .with_ignored(status.is_ignored())
69                .with_untracked(status.is_wt_new());
70            Some(flags)
71        } else {
72            None
73        }
74    }
75
76    fn is_allowed(&self, status: &Status) -> bool {
77        if self.everything {
78            return true;
79        }
80        if self.cached && !status.is_ignored() && !status.is_wt_new() {
81            return true;
82        }
83        if self.added && status.is_index_new() {
84            return true;
85        }
86        if self.modified && (status.is_index_modified() || status.is_wt_modified()) {
87            return true;
88        }
89        if self.renamed && (status.is_index_renamed() || status.is_wt_renamed()) {
90            return true;
91        }
92        if self.ignored && status.is_ignored() {
93            return true;
94        }
95        if self.untracked && status.is_wt_new() {
96            return true;
97        }
98        false
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use crate::git::flags::GitFlags;
105    use git2::Status;
106
107    #[test]
108    fn test_files_are_included_with_cached_flag() {
109        let flags = GitFlags::new().with_cached(true);
110        assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
111        assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
112        assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
113        assert_eq!(true, flags.is_allowed(&Status::INDEX_DELETED));
114        assert_eq!(true, flags.is_allowed(&Status::INDEX_TYPECHANGE));
115        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
116        assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
117        assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
118        assert_eq!(true, flags.is_allowed(&Status::WT_DELETED));
119        assert_eq!(true, flags.is_allowed(&Status::WT_TYPECHANGE));
120        assert_eq!(true, flags.is_allowed(&Status::WT_UNREADABLE));
121        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
122        assert_eq!(true, flags.is_allowed(&Status::CONFLICTED));
123    }
124
125    #[test]
126    fn test_files_are_included_with_added_flag() {
127        let flags = GitFlags::new().with_added(true);
128        assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
129        assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
130        assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
131        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
132        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
133        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
134        assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
135        assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
136        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
137        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
138        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
139        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
140        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
141    }
142
143    #[test]
144    fn test_files_are_included_with_modified_flag() {
145        let flags = GitFlags::new().with_modified(true);
146        assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
147        assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
148        assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
149        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
150        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
151        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
152        assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
153        assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
154        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
155        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
156        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
157        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
158        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
159    }
160
161    #[test]
162    fn test_files_are_included_with_renamed_flag() {
163        let flags = GitFlags::new().with_renamed(true);
164        assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
165        assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
166        assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
167        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
168        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
169        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
170        assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
171        assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
172        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
173        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
174        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
175        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
176        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
177    }
178
179    #[test]
180    fn test_files_are_included_with_ignored_flag() {
181        let flags = GitFlags::new().with_ignored(true);
182        assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
183        assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
184        assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
185        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
186        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
187        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
188        assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
189        assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
190        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
191        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
192        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
193        assert_eq!(true, flags.is_allowed(&Status::IGNORED));
194        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
195    }
196
197    #[test]
198    fn test_files_are_included_with_untracked_flag() {
199        let flags = GitFlags::new().with_untracked(true);
200        assert_eq!(false, flags.is_allowed(&Status::INDEX_NEW));
201        assert_eq!(false, flags.is_allowed(&Status::INDEX_MODIFIED));
202        assert_eq!(false, flags.is_allowed(&Status::INDEX_RENAMED));
203        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
204        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
205        assert_eq!(true, flags.is_allowed(&Status::WT_NEW));
206        assert_eq!(false, flags.is_allowed(&Status::WT_MODIFIED));
207        assert_eq!(false, flags.is_allowed(&Status::WT_RENAMED));
208        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
209        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
210        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
211        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
212        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
213    }
214
215    #[test]
216    fn test_files_are_included_with_multiple_flags() {
217        let flags = GitFlags::new().with_added(true).with_modified(true).with_renamed(true);
218        assert_eq!(true, flags.is_allowed(&Status::INDEX_NEW));
219        assert_eq!(true, flags.is_allowed(&Status::INDEX_MODIFIED));
220        assert_eq!(true, flags.is_allowed(&Status::INDEX_RENAMED));
221        assert_eq!(false, flags.is_allowed(&Status::INDEX_DELETED));
222        assert_eq!(false, flags.is_allowed(&Status::INDEX_TYPECHANGE));
223        assert_eq!(false, flags.is_allowed(&Status::WT_NEW));
224        assert_eq!(true, flags.is_allowed(&Status::WT_MODIFIED));
225        assert_eq!(true, flags.is_allowed(&Status::WT_RENAMED));
226        assert_eq!(false, flags.is_allowed(&Status::WT_DELETED));
227        assert_eq!(false, flags.is_allowed(&Status::WT_TYPECHANGE));
228        assert_eq!(false, flags.is_allowed(&Status::WT_UNREADABLE));
229        assert_eq!(false, flags.is_allowed(&Status::IGNORED));
230        assert_eq!(false, flags.is_allowed(&Status::CONFLICTED));
231    }
232}