git2version/
gitinfo.rs

1use serde::{Deserialize, Serialize};
2use std::fmt::{self, Debug, Display, Formatter};
3
4#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub struct TagInfo<'a> {
6    /// The name of the tag
7    pub tag: &'a str,
8
9    /// The number of commits since the tag
10    pub commits_since_tag: u32,
11}
12
13#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(bound(deserialize = "'de: 'a"))]
15pub struct GitInfo<'a, 'b> {
16    /// Information on the tag that is the closest ancestor tag to the current commit.
17    /// tag_info can be `None` if the repository doesn't have any tags or is a shallow clone and tags aren't available
18    pub tag_info: Option<TagInfo<'a>>,
19
20    /// ID of the current commit
21    pub commit_id: &'b str,
22
23    /// Whether the working directory was modified or whether the build was done from a clean working directory
24    pub modified: bool,
25}
26
27impl<'a, 'b> Debug for GitInfo<'a, 'b> {
28    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
29        Display::fmt(self, f)
30    }
31}
32
33impl<'a, 'b> Display for GitInfo<'a, 'b> {
34    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
35        if let Some(tag) = self.tag_info {
36            write!(f, "{}+{}", tag.tag, tag.commits_since_tag)?;
37        } else {
38            write!(f, "unknown")?;
39        }
40        write!(f, ".g{}", self.commit_id)?;
41        if self.modified {
42            write!(f, ".modified")?;
43        }
44        Ok(())
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    mod display {
53        use super::*;
54
55        #[test]
56        fn notag_notmodified() {
57            let version = GitInfo {
58                tag_info: None,
59                commit_id: "abcdef",
60                modified: false,
61            };
62            assert_eq!("unknown.gabcdef", format!("{}", version));
63            assert_eq!("unknown.gabcdef", format!("{:?}", version));
64        }
65
66        #[test]
67        fn notag_modified() {
68            let version = GitInfo {
69                tag_info: None,
70                commit_id: "abcdef",
71                modified: true,
72            };
73            assert_eq!("unknown.gabcdef.modified", format!("{}", version));
74            assert_eq!("unknown.gabcdef.modified", format!("{:?}", version));
75        }
76
77        #[test]
78        fn notontag_notmodified() {
79            let version = GitInfo {
80                tag_info: Some(TagInfo {
81                    tag: "v1.2.3",
82                    commits_since_tag: 10,
83                }),
84                commit_id: "abcdef",
85                modified: false,
86            };
87            assert_eq!("v1.2.3+10.gabcdef", format!("{}", version));
88            assert_eq!("v1.2.3+10.gabcdef", format!("{:?}", version));
89        }
90
91        #[test]
92        fn notontag_modified() {
93            let version = GitInfo {
94                tag_info: Some(TagInfo {
95                    tag: "v1.2.3",
96                    commits_since_tag: 10,
97                }),
98                commit_id: "abcdef",
99                modified: true,
100            };
101            assert_eq!("v1.2.3+10.gabcdef.modified", format!("{}", version));
102            assert_eq!("v1.2.3+10.gabcdef.modified", format!("{:?}", version));
103        }
104
105        #[test]
106        fn ontag_notmodified() {
107            let version = GitInfo {
108                tag_info: Some(TagInfo {
109                    tag: "v1.2.3",
110                    commits_since_tag: 0,
111                }),
112                commit_id: "abcdef",
113                modified: false,
114            };
115            assert_eq!("v1.2.3+0.gabcdef", format!("{}", version));
116            assert_eq!("v1.2.3+0.gabcdef", format!("{:?}", version));
117        }
118
119        #[test]
120        fn ontag_modified() {
121            let version = GitInfo {
122                tag_info: Some(TagInfo {
123                    tag: "v1.2.3",
124                    commits_since_tag: 0,
125                }),
126                commit_id: "abcdef",
127                modified: true,
128            };
129            assert_eq!("v1.2.3+0.gabcdef.modified", format!("{}", version));
130            assert_eq!("v1.2.3+0.gabcdef.modified", format!("{:?}", version));
131        }
132    }
133}