1use std::path::Path;
2
3use crate::CommandError;
4
5#[must_use]
7pub fn new() -> RevParse<'static> {
8 RevParse::new()
9}
10
11#[derive(Debug)]
15pub struct RevParse<'a> {
16 repo_path: Option<&'a Path>,
17 abbrev_ref: bool,
18 symbolic_full_name: bool,
19 rev: Option<&'a str>,
20}
21
22impl<'a> RevParse<'a> {
23 #[must_use]
24 fn new() -> Self {
25 Self {
26 repo_path: None,
27 abbrev_ref: false,
28 symbolic_full_name: false,
29 rev: None,
30 }
31 }
32
33 #[must_use]
35 pub fn repo_path(mut self, path: &'a Path) -> Self {
36 self.repo_path = Some(path);
37 self
38 }
39
40 crate::flag_methods! {
41 pub fn abbrev_ref / abbrev_ref_if, abbrev_ref, "Conditionally output short ref name."
45 }
46
47 crate::flag_methods! {
48 pub fn symbolic_full_name / symbolic_full_name_if, symbolic_full_name, "Conditionally output full symbolic ref name."
52 }
53
54 #[must_use]
56 pub fn rev(mut self, rev: &'a str) -> Self {
57 self.rev = Some(rev);
58 self
59 }
60
61 #[must_use]
63 pub fn stdout(self) -> cmd_proc::Capture {
64 self.build().stdout()
65 }
66
67 pub fn output(self) -> Result<cmd_proc::Output, CommandError> {
71 self.build().output()
72 }
73
74 fn build(self) -> cmd_proc::Command {
75 crate::base_command(self.repo_path)
76 .argument("rev-parse")
77 .optional_argument(self.abbrev_ref.then_some("--abbrev-ref"))
78 .optional_argument(self.symbolic_full_name.then_some("--symbolic-full-name"))
79 .optional_argument(self.rev)
80 }
81}
82
83impl Default for RevParse<'_> {
84 fn default() -> Self {
85 Self::new()
86 }
87}
88
89#[cfg(feature = "test-utils")]
90impl RevParse<'_> {
91 pub fn test_eq(&self, other: &cmd_proc::Command) {
95 let command = Self {
97 repo_path: self.repo_path,
98 abbrev_ref: self.abbrev_ref,
99 symbolic_full_name: self.symbolic_full_name,
100 rev: self.rev,
101 }
102 .build();
103 command.test_eq(other);
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_rev_parse_head() {
113 let output = RevParse::new().rev("HEAD").stdout().string().unwrap();
114 assert!(!output.trim().is_empty());
115 }
116
117 #[test]
118 fn test_rev_parse_abbrev_ref() {
119 let output = RevParse::new()
120 .abbrev_ref()
121 .rev("HEAD")
122 .stdout()
123 .string()
124 .unwrap();
125 assert!(!output.trim().is_empty());
126 }
127}