thin_fetch/command/
ls_refs.rs1use std::str::FromStr;
2
3use crate::{Command, Error, HashKind, Reference, WithError, bail, command::Execute};
4
5#[derive(Default)]
21pub struct LsRefs {
22 pub peel: bool,
23 pub symrefs: bool,
24 pub unborn: bool,
25 pub ref_prefix: Option<String>,
26 pub hash_kind: HashKind,
27}
28
29impl From<&LsRefs> for Command {
30 fn from(value: &LsRefs) -> Self {
31 let mut cmd = Command::new("ls-refs").object_format(value.hash_kind);
32
33 if value.peel {
34 cmd = cmd.arg("peel");
35 }
36 if value.symrefs {
37 cmd = cmd.arg("symrefs");
38 }
39 if value.unborn {
40 cmd = cmd.arg("unborn");
41 }
42 if let Some(ref_prefix) = &value.ref_prefix {
43 cmd = cmd.arg(format!("ref-prefix {ref_prefix}"));
44 }
45
46 cmd
47 }
48}
49
50impl Execute for LsRefs {
51 type Output = Vec<Reference>;
52
53 fn execute(&self, repo: &crate::Repo) -> Result<Self::Output, Error> {
54 let cmd = self.into();
55 let parcel = repo.call(&cmd)?;
56
57 if parcel.sections.is_empty() {
58 return Ok(vec![]);
59 }
60
61 if parcel.sections.len() > 1 {
62 bail!("expected 1 response, got {}", parcel.sections.len());
63 }
64
65 let refs = parcel.sections.into_iter().next().unwrap();
66
67 refs.chunks
68 .into_iter()
69 .map(|a| {
70 let str = String::from_utf8(a).with_err_msg("could not decode ref as utf-8");
71 str.and_then(|s| Reference::from_str(&s).with_err_msg("could not parse reference"))
72 })
73 .collect()
74 }
75}