1use std::collections::BTreeMap;
6
7use failure::Fail;
8
9#[derive(Debug, Fail)]
10pub enum Error {
11 #[fail(display = "lsdiff error {}", _0)]
12 Lsdiff(lsdiff_rs::Error),
13}
14
15pub type SplitdiffResult<T> = Result<T, Error>;
16
17pub struct PatchData(pub BTreeMap<String, Vec<Vec<String>>>);
18
19pub struct SplitDiff {
20 patch: String,
21}
22
23impl SplitDiff {
24 pub fn new(patch: &str) -> Self {
25 Self { patch: patch.to_owned() }
26 }
27
28 pub fn process(&self) -> SplitdiffResult<PatchData> {
29 let lines: Vec<&str> = self.patch.split('\n').map(|line| line.trim()).collect();
30
31 let mut data = BTreeMap::new();
32 for entry in lsdiff_rs::process(&self.patch).map_err(Error::Lsdiff)? {
33 let slice = &lines[entry.start_line..entry.start_line + entry.lines_count];
34 let hunk = slice.iter().map(|v| v.to_string()).collect();
35 data.entry(entry.input_path)
36 .or_insert_with(Vec::new)
37 .push(hunk);
38 }
39 Ok(PatchData(data))
40 }
41}