use std::str::FromStr;
use crate::{Command, Error, HashKind, Reference, WithError, bail, command::Execute};
#[derive(Default)]
pub struct LsRefs {
pub peel: bool,
pub symrefs: bool,
pub unborn: bool,
pub ref_prefix: Option<String>,
pub hash_kind: HashKind,
}
impl From<&LsRefs> for Command {
fn from(value: &LsRefs) -> Self {
let mut cmd = Command::new("ls-refs").object_format(value.hash_kind);
if value.peel {
cmd = cmd.arg("peel");
}
if value.symrefs {
cmd = cmd.arg("symrefs");
}
if value.unborn {
cmd = cmd.arg("unborn");
}
if let Some(ref_prefix) = &value.ref_prefix {
cmd = cmd.arg(format!("ref-prefix {ref_prefix}"));
}
cmd
}
}
impl Execute for LsRefs {
type Output = Vec<Reference>;
fn execute(&self, repo: &crate::Repo) -> Result<Self::Output, Error> {
let cmd = self.into();
let parcel = repo.call(&cmd)?;
if parcel.sections.is_empty() {
return Ok(vec![]);
}
if parcel.sections.len() > 1 {
bail!("expected 1 response, got {}", parcel.sections.len());
}
let refs = parcel.sections.into_iter().next().unwrap();
refs.chunks
.into_iter()
.map(|a| {
let str = String::from_utf8(a).with_err_msg("could not decode ref as utf-8");
str.and_then(|s| Reference::from_str(&s).with_err_msg("could not parse reference"))
})
.collect()
}
}