aether_evals/evals/
diff.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct GitDiff {
5 pub diff: String,
6 pub stats: DiffStats,
7}
8
9impl GitDiff {
10 pub(crate) fn new(diff: String) -> Self {
11 Self { stats: DiffStats::from_diff(&diff), diff }
12 }
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct DiffStats {
17 pub files_changed: usize,
18 pub lines_added: usize,
19 pub lines_removed: usize,
20}
21
22impl DiffStats {
23 pub fn from_diff(diff: &str) -> Self {
24 let mut lines_added = 0;
25 let mut lines_removed = 0;
26 let mut files_changed = 0;
27
28 for line in diff.lines() {
29 if line.starts_with("diff --git") {
30 files_changed += 1;
31 } else if line.starts_with('+') && !line.starts_with("+++") {
32 lines_added += 1;
33 } else if line.starts_with('-') && !line.starts_with("---") {
34 lines_removed += 1;
35 }
36 }
37
38 Self { files_changed, lines_added, lines_removed }
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn diff_stats_from_diff_counts_files_and_changed_lines() {
48 let diff = "diff --git a/a.txt b/a.txt\n--- a/a.txt\n+++ b/a.txt\n@@\n-old\n+new\ndiff --git a/b.txt b/b.txt\n+++ b/b.txt\n+added\n";
49
50 let stats = DiffStats::from_diff(diff);
51
52 assert_eq!(stats.files_changed, 2);
53 assert_eq!(stats.lines_added, 2);
54 assert_eq!(stats.lines_removed, 1);
55 }
56}