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
6
    pub fn name(&self) -> Option<&str> {
9
6
        self.0.name()
10
6
    }
11

            
12
    /// Return the shorthand name of the reference, e.g. "main" for "refs/heads/main".
13
21
    pub fn shorthand(&self) -> Option<&str> {
14
21
        self.0.shorthand()
15
21
    }
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
3
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
28
3
        match self.shorthand() {
29
3
            Some(name) => write!(f, "{}", name),
30
            None => write!(f, "<unnamed>"),
31
        }
32
3
    }
33
}
34

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

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

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

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

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

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

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

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

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

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

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