From a11bedacaa075c07423254623ee7b91b5cb571a0 Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Tue, 20 Sep 2022 11:17:27 +0200 Subject: [PATCH] git-types: Add `stats` method to `diff::Diff` The information on how many line insertions and deletions happened in a diff, as well as files changed is something that is used multiple times downstream, so it makes the code terser by implementing this function here. Signed-off-by: Sebastian Martinez --- radicle-surf/src/diff.rs | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/radicle-surf/src/diff.rs b/radicle-surf/src/diff.rs index 5ef20a4..353b5f9 100644 --- a/radicle-surf/src/diff.rs +++ b/radicle-surf/src/diff.rs @@ -121,6 +121,22 @@ pub enum FileDiff { }, } +/// Statistics describing a particular [`Diff`]. +#[cfg_attr( + feature = "serialize", + derive(Serialize), + serde(rename_all = "camelCase") +)] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Stats { + /// Get the total number of files changed in a diff. + pub files_changed: usize, + /// Get the total number of insertions in a diff. + pub insertions: usize, + /// Get the total number of deletions in a diff. + pub deletions: usize, +} + /// A set of line changes. #[cfg_attr( feature = "serialize", @@ -528,6 +544,55 @@ impl Diff { }); self.deleted.append(&mut new_files); } + + pub fn stats(&self) -> Stats { + let mut deletions = 0; + let mut insertions = 0; + + for file in &self.modified { + if let self::FileDiff::Plain { ref hunks } = file.diff { + for hunk in hunks.iter() { + for line in &hunk.lines { + match line { + self::LineDiff::Addition { .. } => insertions += 1, + self::LineDiff::Deletion { .. } => deletions += 1, + _ => {}, + } + } + } + } + } + + for file in &self.created { + if let self::FileDiff::Plain { ref hunks } = file.diff { + for hunk in hunks.iter() { + for line in &hunk.lines { + if let self::LineDiff::Addition { .. } = line { + insertions += 1 + } + } + } + } + } + + for file in &self.deleted { + if let self::FileDiff::Plain { ref hunks } = file.diff { + for hunk in hunks.iter() { + for line in &hunk.lines { + if let self::LineDiff::Deletion { .. } = line { + deletions += 1 + } + } + } + } + } + + Stats { + files_changed: self.modified.len() + self.created.len() + self.deleted.len(), + insertions, + deletions, + } + } } #[cfg(test)]