From 097d01350d8284761427084c08954281baa5ce3e Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Fri, 29 Sep 2023 13:52:42 +0200 Subject: [PATCH] surf: Add `stats` property to each `DiffContent::Plain` This allows us to get the additions and deletions for each file in a diff. Signed-off-by: Sebastian Martinez --- radicle-surf/src/diff.rs | 29 ++++++++++++++++++++++++----- radicle-surf/src/diff/git.rs | 15 +++++++++++++++ radicle-surf/t/src/diff.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/radicle-surf/src/diff.rs b/radicle-surf/src/diff.rs index 9ebcd3c..21c6e91 100644 --- a/radicle-surf/src/diff.rs +++ b/radicle-surf/src/diff.rs @@ -288,6 +288,7 @@ pub enum DiffContent { #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] Plain { hunks: Hunks, + stats: FileStats, eof: EofNewLine, }, Empty, @@ -296,10 +297,18 @@ pub enum DiffContent { impl DiffContent { pub fn eof(&self) -> Option { match self { - Self::Plain { hunks: _, eof } => Some(eof.clone()), + Self::Plain { eof, .. } => Some(eof.clone()), _ => None, } } + + pub fn stats(&self) -> Option<&FileStats> { + match &self { + DiffContent::Plain { stats, .. } => Some(stats), + DiffContent::Empty => None, + DiffContent::Binary => None, + } + } } /// File mode in a diff. @@ -371,11 +380,11 @@ impl Serialize for FileDiff { match &self { FileDiff::Added(x) => { state.serialize_field("path", &x.path)?; - state.serialize_field("diff", &x.diff)? + state.serialize_field("diff", &x.diff)?; }, FileDiff::Deleted(x) => { state.serialize_field("path", &x.path)?; - state.serialize_field("diff", &x.diff)? + state.serialize_field("diff", &x.diff)?; }, FileDiff::Modified(x) => { state.serialize_field("path", &x.path)?; @@ -383,11 +392,11 @@ impl Serialize for FileDiff { }, FileDiff::Moved(x) => { state.serialize_field("oldPath", &x.old_path)?; - state.serialize_field("newPath", &x.new_path)? + state.serialize_field("newPath", &x.new_path)?; }, FileDiff::Copied(x) => { state.serialize_field("oldPath", &x.old_path)?; - state.serialize_field("newPath", &x.new_path)? + state.serialize_field("newPath", &x.new_path)?; }, } state.end() @@ -411,6 +420,16 @@ impl Serialize for Diff { } } +/// Statistics describing a particular [`FileDiff`]. +#[cfg_attr(feature = "serde", derive(Serialize), serde(rename_all = "camelCase"))] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] +pub struct FileStats { + /// Get the total number of additions in a [`FileDiff`]. + pub additions: usize, + /// Get the total number of deletions in a [`FileDiff`]. + pub deletions: usize, +} + /// Statistics describing a particular [`Diff`]. #[cfg_attr(feature = "serde", derive(Serialize), serde(rename_all = "camelCase"))] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] diff --git a/radicle-surf/src/diff/git.rs b/radicle-surf/src/diff/git.rs index 0ff0a9c..e2bda0a 100644 --- a/radicle-surf/src/diff/git.rs +++ b/radicle-surf/src/diff/git.rs @@ -23,6 +23,7 @@ use super::{ DiffFile, EofNewLine, FileMode, + FileStats, Hunk, Hunks, Line, @@ -152,6 +153,8 @@ impl TryFrom> for DiffContent { let mut hunks = Vec::new(); let mut old_missing_eof = false; let mut new_missing_eof = false; + let mut additions = 0; + let mut deletions = 0; for h in 0..patch.num_hunks() { let (hunk, hunk_lines) = patch.hunk(h)?; @@ -166,11 +169,19 @@ impl TryFrom> for DiffContent { old_missing_eof = true; continue; }, + git2::DiffLineType::Addition => { + additions += 1; + }, + git2::DiffLineType::Deletion => { + deletions += 1; + }, git2::DiffLineType::AddEOFNL => { + additions += 1; old_missing_eof = true; continue; }, git2::DiffLineType::DeleteEOFNL => { + deletions += 1; new_missing_eof = true; continue; }, @@ -194,6 +205,10 @@ impl TryFrom> for DiffContent { }; Ok(DiffContent::Plain { hunks: Hunks(hunks), + stats: FileStats { + additions, + deletions, + }, eof, }) } diff --git a/radicle-surf/t/src/diff.rs b/radicle-surf/t/src/diff.rs index 09165f5..a52fc95 100644 --- a/radicle-surf/t/src/diff.rs +++ b/radicle-surf/t/src/diff.rs @@ -9,6 +9,7 @@ use radicle_surf::{ EofNewLine, FileDiff, FileMode, + FileStats, Hunk, Line, Modification, @@ -48,6 +49,10 @@ fn test_initial_diff() -> Result<(), Error> { new: 1..2, }] .into(), + stats: FileStats { + additions: 1, + deletions: 0, + }, eof: EofNewLine::default(), }, new: DiffFile { @@ -99,6 +104,10 @@ fn test_diff_file() -> Result<(), Error> { new: 1..3, }] .into(), + stats: FileStats { + additions: 2, + deletions: 1 + }, eof: EofNewLine::default(), }, old: DiffFile { @@ -137,6 +146,10 @@ fn test_diff() -> Result<(), Error> { new: 1..3, }] .into(), + stats: FileStats { + additions: 2, + deletions: 1 + }, eof: EofNewLine::default(), }, old: DiffFile { @@ -238,6 +251,10 @@ fn test_diff_serde() -> Result<(), Error> { "old": { "start": 0, "end": 0 }, "new": { "start": 1, "end": 3 }, }], + "stats": { + "additions": 2, + "deletions": 0, + }, "eof": "noneMissing", }, "new": { @@ -295,6 +312,10 @@ fn test_diff_serde() -> Result<(), Error> { "old": { "start": 1, "end": 8 }, "new": { "start": 0, "end": 0 }, }], + "stats": { + "additions": 0, + "deletions": 7, + }, "eof": "noneMissing", }, }], @@ -310,6 +331,10 @@ fn test_diff_serde() -> Result<(), Error> { "diff": { "eof": "noneMissing", "hunks": [], + "stats": { + "additions": 0, + "deletions": 0, + }, "type": "plain", }, "new": { @@ -350,6 +375,10 @@ fn test_diff_serde() -> Result<(), Error> { "old": { "start": 1, "end": 3 }, "new": { "start": 1, "end": 3 }, }], + "stats": { + "additions": 2, + "deletions": 2 + }, "eof": "noneMissing", }, "new": { @@ -553,6 +582,10 @@ index 3f69208f3..cbc843c82 100644 }, }, ], + "stats": { + "additions": 7, + "deletions": 5 + }, "type": "plain", }, "new": {