1
use std::fmt::{Debug, Display, Formatter, Result};
2

            
3
/// A reference to a Git object.
4
pub struct Reference<'a>(git2::Reference<'a>);
5

            
6
impl Reference<'_> {
7
    /// Return the full name of the reference, e.g. "refs/heads/main".
8
4
    pub fn name(&self) -> Option<&str> {
9
4
        self.0.name()
10
4
    }
11

            
12
    /// Return the shorthand name of the reference, e.g. "main" for "refs/heads/main".
13
14
    pub fn shorthand(&self) -> Option<&str> {
14
14
        self.0.shorthand()
15
14
    }
16
}
17

            
18
impl Debug for Reference<'_> {
19
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
20
        f.debug_struct("Reference")
21
            .field("name", &self.name())
22
            .finish()
23
    }
24
}
25

            
26
impl Display for Reference<'_> {
27
2
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
28
2
        match self.shorthand() {
29
2
            Some(name) => write!(f, "{}", name),
30
            None => write!(f, "<unnamed>"),
31
        }
32
2
    }
33
}
34

            
35
impl<'a> From<git2::Reference<'a>> for Reference<'a> {
36
18
    fn from(reference: git2::Reference<'a>) -> Self {
37
18
        Reference(reference)
38
18
    }
39
}
40

            
41
#[cfg(test)]
42
mod tests {
43
    use super::*;
44
    use crate::test_utilities;
45

            
46
    #[test]
47
2
    fn test_name() {
48
        // GIVEN a mock repository with a HEAD reference
49
2
        let (_tempdir, repo) = test_utilities::create_mock_repo();
50
2
        let reference = repo.head().unwrap();
51

            
52
        // WHEN we get the name of the reference
53
2
        let binding = Reference::from(reference);
54
2
        let name = binding.name().unwrap();
55

            
56
        // THEN the name should be the full reference name
57
2
        assert_eq!(name, "refs/heads/main");
58
2
    }
59

            
60
    #[test]
61
2
    fn test_shorthand() {
62
        // GIVEN a mock repository with a HEAD reference
63
2
        let (_tempdir, repo) = test_utilities::create_mock_repo();
64
2
        let reference = repo.head().unwrap();
65

            
66
        // WHEN we get the shorthand of the reference
67
2
        let binding = Reference::from(reference);
68
2
        let shorthand = binding.shorthand().unwrap();
69

            
70
        // THEN the shorthand should be the name without the prefix
71
2
        assert_eq!(shorthand, "main");
72
2
    }
73

            
74
    #[test]
75
2
    fn test_display() {
76
        // GIVEN a mock repository with a HEAD reference
77
2
        let (_tempdir, repo) = test_utilities::create_mock_repo();
78
2
        let reference = repo.head().unwrap();
79

            
80
        // WHEN we create a Reference and format it
81
2
        let binding = Reference::from(reference);
82

            
83
        // THEN the display should match the short name
84
2
        assert_eq!(format!("{}", binding), "main");
85
2
    }
86
}