use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum RunAbortReason {
Interrupted,
UserRevert,
}
#[derive(Debug)]
pub(crate) struct RunAbort {
reason: RunAbortReason,
message: String,
}
impl RunAbort {
pub(crate) fn new(reason: RunAbortReason, message: impl Into<String>) -> Self {
Self {
reason,
message: message.into(),
}
}
pub(crate) fn reason(&self) -> RunAbortReason {
self.reason
}
}
impl fmt::Display for RunAbort {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for RunAbort {}
pub(crate) fn abort_reason(err: &anyhow::Error) -> Option<RunAbortReason> {
err.chain()
.find_map(|cause| cause.downcast_ref::<RunAbort>().map(RunAbort::reason))
}
pub(crate) fn is_dirty_repo_error(err: &anyhow::Error) -> bool {
err.chain().any(|cause| {
cause
.downcast_ref::<crate::git::GitError>()
.is_some_and(|e| matches!(e, crate::git::GitError::DirtyRepo { .. }))
})
}
pub(crate) fn is_queue_validation_error(err: &anyhow::Error) -> bool {
err.chain().any(|cause| {
let msg = cause.to_string();
msg.contains("relationship")
|| msg.contains("Duplicate task ID")
|| msg.contains("Circular blocking")
|| msg.starts_with("Self-")
|| msg.starts_with("Invalid ")
|| msg.starts_with("Missing ")
|| msg.starts_with("Unsupported queue.json")
|| msg.starts_with("Empty id_prefix")
|| msg.starts_with("Invalid id_width")
})
}