use std::{collections::HashMap, str::FromStr};
use crate::{Error, WithError as _};
#[derive(Debug, Clone)]
pub struct Reference {
pub hash: String,
pub name: String,
pub peeled: Option<String>,
pub symref_target: Option<String>,
}
impl Reference {
#[must_use]
pub fn target(&self) -> &str {
if let Some(ref peeled) = self.peeled {
peeled
} else {
&self.hash
}
}
}
impl FromStr for Reference {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.trim_end().split(' ');
let hash = parts.next().with_err_msg("hash not found")?;
let name = parts.next().with_err_msg("name not found")?;
let mut res = Self {
hash: hash.to_owned(),
name: name.to_owned(),
peeled: None,
symref_target: None,
};
let mut args = parts
.filter_map(|arg| arg.split_once(':'))
.collect::<HashMap<&str, &str>>();
if let Some(peeled) = args.remove("peeled") {
res.peeled.replace(peeled.to_owned());
}
if let Some(value) = args.remove("symref-target") {
res.symref_target.replace(value.to_owned());
}
assert!(args.is_empty(), "unparsed args: {args:?}");
Ok(res)
}
}