git_disjoint/
issue_group.rs1use std::{error::Error, fmt::Display};
2
3use git2::Commit;
4
5use crate::issue::Issue;
6
7#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct GitCommitSummary(pub String);
9
10impl Display for GitCommitSummary {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 write!(f, "{}", self.0)
13 }
14}
15
16#[derive(Debug)]
17#[non_exhaustive]
18pub struct FromCommitError {
19 commit: git2::Oid,
20 kind: FromCommitErrorKind,
21}
22
23impl Display for FromCommitError {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 match &self.kind {
26 FromCommitErrorKind::InvalidUtf8 => {
27 write!(f, "summary for commit {:?} is not valid UTF-8", self.commit)
28 }
29 }
30 }
31}
32
33impl Error for FromCommitError {
34 fn source(&self) -> Option<&(dyn Error + 'static)> {
35 match &self.kind {
36 FromCommitErrorKind::InvalidUtf8 => None,
37 }
38 }
39}
40
41#[derive(Debug)]
42pub enum FromCommitErrorKind {
43 #[non_exhaustive]
44 InvalidUtf8,
45}
46
47impl TryFrom<&Commit<'_>> for GitCommitSummary {
48 type Error = FromCommitError;
49
50 fn try_from(commit: &Commit) -> Result<Self, Self::Error> {
51 Ok(Self(
52 commit
53 .summary()
54 .ok_or(FromCommitError {
55 commit: commit.id(),
56 kind: FromCommitErrorKind::InvalidUtf8,
57 })?
58 .to_owned(),
59 ))
60 }
61}
62
63#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
64pub enum IssueGroup {
65 Issue(Issue),
66 Commit(GitCommitSummary),
67}
68
69impl Display for IssueGroup {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 match self {
72 IssueGroup::Issue(issue) => write!(f, "{issue}"),
73 IssueGroup::Commit(commit) => write!(f, "{commit}"),
74 }
75 }
76}
77
78impl From<GitCommitSummary> for IssueGroup {
79 fn from(value: GitCommitSummary) -> Self {
80 Self::Commit(value)
81 }
82}
83
84impl From<Issue> for IssueGroup {
85 fn from(value: Issue) -> Self {
86 Self::Issue(value)
87 }
88}
89
90#[cfg(test)]
91mod test_display {
92 use crate::{issue::Issue, issue_group::GitCommitSummary};
93
94 use super::IssueGroup;
95
96 fn check<I: Into<IssueGroup>>(issue_group: I, displays_as: &str) {
97 assert_eq!(displays_as, format!("{}", issue_group.into()));
98 }
99
100 #[test]
101 fn display_human_readable_issue() {
102 check(Issue::Jira("COOL-123".to_string()), "Jira COOL-123");
103 }
104
105 #[test]
106 fn display_human_readable_commit() {
107 check(
108 GitCommitSummary(String::from("this is a cool summary")),
109 "this is a cool summary",
110 );
111 }
112}