use objects::object::ChangeId;
use super::{Head, UNDO_RECOVERY_HANDLE};
pub fn resolve_refspec<E, ReadHead, GetThread, GetMarker, GetUndoRecovery>(
refspec: &str,
read_head: ReadHead,
get_thread: GetThread,
get_marker: GetMarker,
get_undo_recovery: GetUndoRecovery,
) -> Result<Option<ChangeId>, E>
where
ReadHead: FnOnce() -> Result<Head, E>,
GetThread: Fn(&str) -> Result<Option<ChangeId>, E>,
GetMarker: Fn(&str) -> Result<Option<ChangeId>, E>,
GetUndoRecovery: FnOnce() -> Result<Option<ChangeId>, E>,
{
if refspec == "@" || refspec == "HEAD" {
return match read_head()? {
Head::Attached { thread } => get_thread(&thread),
Head::Detached { state } => Ok(Some(state)),
};
}
if refspec == UNDO_RECOVERY_HANDLE {
return get_undo_recovery();
}
if let Some(id) = get_thread(refspec)? {
return Ok(Some(id));
}
if let Some(id) = get_marker(refspec)? {
return Ok(Some(id));
}
if let Ok(id) = ChangeId::parse(refspec) {
return Ok(Some(id));
}
Ok(None)
}