1use failure::Fail;
6
7#[derive(Default)]
8pub struct Entry {
9 pub start_line: usize,
11 pub hunk_start_line: usize,
13 pub input_path: String,
15 pub output_path: String,
17 pub lines_count: usize,
19}
20
21#[derive(Debug, Fail)]
22pub enum Error {
23 #[fail(display = "The patch is malformed at line {}", _0)]
24 MalformedPatch(usize),
25}
26
27pub type LsdiffResult<T> = Result<T, Error>;
28
29pub fn process(patch: &str) -> LsdiffResult<Vec<Entry>> {
30 let lines: Vec<&str> = patch.split('\n').map(|line| line.trim()).collect();
31
32 let mut entries: Vec<Entry> = Vec::new();
33
34 for index in 0..lines.len() - 1 {
35 if !(lines[index].starts_with("---") && lines[index + 1].starts_with("+++")) {
36 continue;
37 }
38
39 let mut entry = Entry::default();
40 entry.start_line = index;
41 entry.hunk_start_line = index + 2;
42
43 if let Some(last) = entries.last_mut() {
44 last.lines_count = entry.start_line - last.start_line;
45 }
46
47 let elements: Vec<&str> = lines[index].split(' ').collect();
48 if elements.len() < 2 {
49 return Err(Error::MalformedPatch(index + 1));
50 }
51 entry.input_path = elements[1].to_owned();
52
53 let elements: Vec<&str> = lines[index + 1].split(' ').collect();
54 if elements.len() < 2 {
55 return Err(Error::MalformedPatch(index + 2));
56 }
57 entry.output_path = elements[1].to_owned();
58
59 entries.push(entry)
60 }
61
62 if let Some(last) = entries.last_mut() {
63 last.lines_count = lines.len() - 1 - last.start_line;
64 }
65
66 Ok(entries)
67}