uv_git_types/
reference.rs1use std::fmt::Display;
2use std::str;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
6pub enum GitReference {
7 Branch(String),
9 Tag(String),
11 BranchOrTag(String),
13 BranchOrTagOrCommit(String),
15 NamedRef(String),
17 DefaultBranch,
19}
20
21impl GitReference {
22 pub fn from_rev(rev: String) -> Self {
25 if rev.starts_with("refs/") {
26 Self::NamedRef(rev)
27 } else if looks_like_commit_hash(&rev) {
28 Self::BranchOrTagOrCommit(rev)
29 } else {
30 Self::BranchOrTag(rev)
31 }
32 }
33
34 pub fn as_str(&self) -> Option<&str> {
36 match self {
37 Self::Tag(rev) => Some(rev),
38 Self::Branch(rev) => Some(rev),
39 Self::BranchOrTag(rev) => Some(rev),
40 Self::BranchOrTagOrCommit(rev) => Some(rev),
41 Self::NamedRef(rev) => Some(rev),
42 Self::DefaultBranch => None,
43 }
44 }
45
46 pub fn as_rev(&self) -> &str {
48 match self {
49 Self::Tag(rev) => rev,
50 Self::Branch(rev) => rev,
51 Self::BranchOrTag(rev) => rev,
52 Self::BranchOrTagOrCommit(rev) => rev,
53 Self::NamedRef(rev) => rev,
54 Self::DefaultBranch => "HEAD",
55 }
56 }
57
58 pub fn kind_str(&self) -> &str {
60 match self {
61 Self::Branch(_) => "branch",
62 Self::Tag(_) => "tag",
63 Self::BranchOrTag(_) => "branch or tag",
64 Self::BranchOrTagOrCommit(_) => "branch, tag, or commit",
65 Self::NamedRef(_) => "ref",
66 Self::DefaultBranch => "default branch",
67 }
68 }
69}
70
71impl Display for GitReference {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 write!(f, "{}", self.as_str().unwrap_or("HEAD"))
74 }
75}
76
77fn looks_like_commit_hash(rev: &str) -> bool {
79 rev.len() >= 7 && rev.chars().all(|ch| ch.is_ascii_hexdigit())
80}