1use std::path::{Path, PathBuf};
2
3use super::{delta::Delta, status::Status};
4use crate::file_mode::FileMode;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct FileStatus {
9 pub(crate) deltas: Vec<Delta>,
10 pub(crate) destination_is_binary: bool,
11 pub(crate) destination_mode: FileMode,
12 pub(crate) destination_path: PathBuf,
13 pub(crate) largest_new_line_number: u32,
14 pub(crate) largest_old_line_number: u32,
15 pub(crate) source_is_binary: bool,
16 pub(crate) source_mode: FileMode,
17 pub(crate) source_path: PathBuf,
18 pub(crate) status: Status,
19}
20
21impl FileStatus {
22 #[inline]
24 #[must_use]
25 pub(crate) fn new<F: AsRef<Path>>(
26 source_path: F,
27 source_mode: FileMode,
28 source_is_binary: bool,
29 destination_path: F,
30 destination_mode: FileMode,
31 destination_is_binary: bool,
32 status: Status,
33 ) -> Self {
34 Self {
35 deltas: vec![],
36 destination_is_binary,
37 destination_mode,
38 destination_path: PathBuf::from(destination_path.as_ref()),
39 largest_new_line_number: 0,
40 largest_old_line_number: 0,
41 source_is_binary,
42 source_mode,
43 source_path: PathBuf::from(source_path.as_ref()),
44 status,
45 }
46 }
47
48 #[inline]
50 pub fn add_delta(&mut self, delta: Delta) {
51 let last_old_line_number = delta.old_lines_start() + delta.old_number_lines();
52 if self.largest_old_line_number < last_old_line_number {
53 self.largest_old_line_number = last_old_line_number;
54 }
55 let last_new_line_number = delta.new_lines_start() + delta.new_number_lines();
56 if self.largest_new_line_number < last_new_line_number {
57 self.largest_new_line_number = last_new_line_number;
58 }
59 self.deltas.push(delta);
60 }
61
62 #[inline]
64 #[must_use]
65 pub const fn status(&self) -> Status {
66 self.status
67 }
68
69 #[inline]
71 #[must_use]
72 pub fn destination_path(&self) -> &Path {
73 self.destination_path.as_path()
74 }
75
76 #[inline]
78 #[must_use]
79 pub const fn destination_mode(&self) -> FileMode {
80 self.destination_mode
81 }
82
83 #[inline]
85 #[must_use]
86 pub const fn destination_is_binary(&self) -> bool {
87 self.destination_is_binary
88 }
89
90 #[inline]
92 #[must_use]
93 pub fn source_path(&self) -> &Path {
94 self.source_path.as_path()
95 }
96
97 #[inline]
99 #[must_use]
100 pub const fn source_mode(&self) -> FileMode {
101 self.source_mode
102 }
103
104 #[inline]
106 #[must_use]
107 pub const fn source_is_binary(&self) -> bool {
108 self.source_is_binary
109 }
110
111 #[inline]
113 #[must_use]
114 pub const fn deltas(&self) -> &Vec<Delta> {
115 &self.deltas
116 }
117
118 #[inline]
120 #[must_use]
121 pub const fn last_old_line_number(&self) -> u32 {
122 self.largest_old_line_number
123 }
124
125 #[inline]
127 #[must_use]
128 pub const fn last_new_line_number(&self) -> u32 {
129 self.largest_new_line_number
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use testutils::assert_empty;
136
137 use super::*;
138
139 fn create_file_stat() -> FileStatus {
140 FileStatus::new(
141 Path::new("/from/path"),
142 FileMode::Normal,
143 false,
144 Path::new("/to/path"),
145 FileMode::Executable,
146 false,
147 Status::Modified,
148 )
149 }
150
151 #[test]
152 fn status() {
153 assert_eq!(create_file_stat().status(), Status::Modified);
154 }
155
156 #[test]
157 fn destination_path() {
158 assert_eq!(create_file_stat().destination_path(), PathBuf::from("/to/path"));
159 }
160
161 #[test]
162 fn destination_mode() {
163 assert_eq!(create_file_stat().destination_mode(), FileMode::Executable);
164 }
165
166 #[test]
167 fn destination_is_binary() {
168 assert!(!create_file_stat().destination_is_binary());
169 }
170
171 #[test]
172 fn source_path() {
173 assert_eq!(create_file_stat().source_path(), PathBuf::from("/from/path"));
174 }
175
176 #[test]
177 fn source_mode() {
178 assert_eq!(create_file_stat().source_mode(), FileMode::Normal);
179 }
180
181 #[test]
182 fn source_is_binary() {
183 assert!(!create_file_stat().source_is_binary());
184 }
185
186 #[test]
187 fn deltas_empty() {
188 let file_stat = create_file_stat();
189 assert_empty!(file_stat.deltas());
190 assert_eq!(file_stat.last_old_line_number(), 0);
191 assert_eq!(file_stat.last_new_line_number(), 0);
192 }
193
194 #[test]
195 fn deltas_single() {
196 let mut file_stat = create_file_stat();
197 let delta = Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 12, 3, 4);
198 file_stat.add_delta(delta.clone());
199 assert_eq!(file_stat.deltas(), &vec![delta]);
200 assert_eq!(file_stat.last_old_line_number(), 13);
201 assert_eq!(file_stat.last_new_line_number(), 16);
202 }
203
204 #[test]
205 fn deltas_multiple() {
206 let mut file_stat = create_file_stat();
207 let delta1 = Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 12, 3, 4);
208 let delta2 = Delta::new("@ path/to/file.rs:156 @ impl Delta {", 110, 2, 10, 3);
209 file_stat.add_delta(delta1.clone());
210 file_stat.add_delta(delta2.clone());
211 assert_eq!(file_stat.deltas(), &vec![delta1, delta2]);
212 assert_eq!(file_stat.last_old_line_number(), 120);
213 assert_eq!(file_stat.last_new_line_number(), 16);
214 }
215
216 #[test]
217 fn deltas_with_second_delta_with_larger_old_line_number() {
218 let mut file_stat = create_file_stat();
219 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
220 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 20, 20, 5, 5));
221 assert_eq!(file_stat.last_old_line_number(), 25);
222 }
223
224 #[test]
225 fn deltas_with_first_delta_with_larger_old_line_number() {
226 let mut file_stat = create_file_stat();
227 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 20, 20, 5, 5));
228 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
229 assert_eq!(file_stat.last_old_line_number(), 25);
230 }
231
232 #[test]
233 fn deltas_with_second_delta_with_larger_new_line_number() {
234 let mut file_stat = create_file_stat();
235 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 10, 5, 5));
236 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
237 assert_eq!(file_stat.last_new_line_number(), 25);
238 }
239
240 #[test]
241 fn deltas_with_first_delta_with_larger_new_line_number() {
242 let mut file_stat = create_file_stat();
243 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 20, 5, 5));
244 file_stat.add_delta(Delta::new("@ path/to/file.rs:56 @ impl Delta {", 10, 10, 5, 5));
245 assert_eq!(file_stat.last_new_line_number(), 25);
246 }
247}