Skip to main content

rootle_provider/
commit.rs

1//! Commit detail vocabulary. Missing patches/counts are unknown, not proof
2//! that a file is binary or that no lines changed.
3
4use crate::id::{RepoPath, Sha};
5
6#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
7pub struct CommitFile {
8    pub path: RepoPath,
9    pub status: FileStatus,
10    #[serde(default)]
11    pub additions: Option<u32>,
12    #[serde(default)]
13    pub deletions: Option<u32>,
14    #[serde(default)]
15    pub patch: Option<String>,
16    #[serde(default)]
17    pub previous_path: Option<RepoPath>,
18    /// True only when the backend has positively identified binary content.
19    #[serde(default)]
20    pub binary: bool,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Deserialize)]
24#[serde(rename_all = "lowercase")]
25pub enum FileStatus {
26    Added,
27    Removed,
28    Renamed,
29    #[default]
30    #[serde(other)]
31    Modified,
32}
33impl FileStatus {
34    pub fn label(self) -> &'static str {
35        match self {
36            Self::Added => "added",
37            Self::Removed => "removed",
38            Self::Renamed => "renamed",
39            Self::Modified => "modified",
40        }
41    }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
45pub struct CommitDetail {
46    pub sha: Sha,
47    pub author: String,
48    pub date: String,
49    pub message: String,
50    #[serde(default)]
51    pub parents: Vec<Sha>,
52    pub files: Vec<CommitFile>,
53    /// The provider stopped at its file budget. This is not a complete list.
54    #[serde(default)]
55    pub truncated: bool,
56    /// Provider-built permalink to this commit, not its repository homepage.
57    #[serde(default)]
58    pub web_url: Option<String>,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub struct CommitStatistics {
63    pub additions: Option<u64>,
64    pub deletions: Option<u64>,
65}
66impl CommitDetail {
67    /// Sum known counts without overflow; retain unknownness per side.
68    pub fn line_stats(&self) -> CommitStatistics {
69        CommitStatistics {
70            additions: self.files.iter().try_fold(0u64, |total, file| {
71                total.checked_add(u64::from(file.additions?))
72            }),
73            deletions: self.files.iter().try_fold(0u64, |total, file| {
74                total.checked_add(u64::from(file.deletions?))
75            }),
76        }
77    }
78}