refactor: ApprovalKind::as_str owns the kind→string mapping
replaces three hand-rolled six-arm matches (actions.rs ×2, state_snapshot.rs); approvals::kind_to_str delegates. a new kind can no longer silently miss one of them
This commit is contained in:
parent
084e12503c
commit
f74c1984d7
4 changed files with 25 additions and 35 deletions
|
|
@ -540,14 +540,7 @@ fn finish_approval(
|
||||||
// snapshot refetch. `approved` rows that succeed get the
|
// snapshot refetch. `approved` rows that succeed get the
|
||||||
// approval's logged resolved_at indirectly via `now_unix()`;
|
// approval's logged resolved_at indirectly via `now_unix()`;
|
||||||
// failures already wrote it via mark_failed above.
|
// failures already wrote it via mark_failed above.
|
||||||
let approval_kind = match approval.kind {
|
let approval_kind = approval.kind.as_str();
|
||||||
ApprovalKind::Spawn => "spawn",
|
|
||||||
ApprovalKind::ApplyCommit => "apply_commit",
|
|
||||||
ApprovalKind::InitConfig => "init_config",
|
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
|
||||||
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
|
||||||
};
|
|
||||||
let sha_short = approval
|
let sha_short = approval
|
||||||
.fetched_sha
|
.fetched_sha
|
||||||
.as_deref()
|
.as_deref()
|
||||||
|
|
@ -1021,14 +1014,7 @@ pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()
|
||||||
tracing::warn!(%id, agent = %a.agent, error = ?e, "forge: push_config after deny failed");
|
tracing::warn!(%id, agent = %a.agent, error = ?e, "forge: push_config after deny failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let approval_kind = match a.kind {
|
let approval_kind = a.kind.as_str();
|
||||||
ApprovalKind::Spawn => "spawn",
|
|
||||||
ApprovalKind::ApplyCommit => "apply_commit",
|
|
||||||
ApprovalKind::InitConfig => "init_config",
|
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
|
||||||
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
|
||||||
};
|
|
||||||
let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned());
|
let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned());
|
||||||
let description = a.description.clone();
|
let description = a.description.clone();
|
||||||
let agent_owned = a.agent.clone();
|
let agent_owned = a.agent.clone();
|
||||||
|
|
|
||||||
|
|
@ -411,18 +411,11 @@ fn row_to_approval(row: &rusqlite::Row<'_>) -> rusqlite::Result<Approval> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stable kind→str mapping used wherever we emit `ApprovalResolved`
|
/// Stable kind→str mapping used wherever we emit `ApprovalResolved`
|
||||||
/// or persist a kind to sqlite. `pub(crate)` so callers like
|
/// or persist a kind to sqlite. Thin alias over
|
||||||
/// `questions::handle_cancel_loose_end` don't have to duplicate the
|
/// [`ApprovalKind::as_str`] (the wire-type owns the mapping) kept for
|
||||||
/// match; bumping a kind here is the single source of truth.
|
/// the existing call sites' name.
|
||||||
pub(crate) fn kind_to_str(kind: ApprovalKind) -> &'static str {
|
pub(crate) fn kind_to_str(kind: ApprovalKind) -> &'static str {
|
||||||
match kind {
|
kind.as_str()
|
||||||
ApprovalKind::ApplyCommit => "apply_commit",
|
|
||||||
ApprovalKind::Spawn => "spawn",
|
|
||||||
ApprovalKind::InitConfig => "init_config",
|
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
|
||||||
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kind_from_str(s: &str) -> Result<ApprovalKind> {
|
fn kind_from_str(s: &str) -> Result<ApprovalKind> {
|
||||||
|
|
|
||||||
|
|
@ -526,14 +526,7 @@ fn history_view(a: Approval) -> ApprovalHistoryView {
|
||||||
// Pending shouldn't appear in recent_resolved, but be defensive.
|
// Pending shouldn't appear in recent_resolved, but be defensive.
|
||||||
hive_sh4re::ApprovalStatus::Pending => "pending",
|
hive_sh4re::ApprovalStatus::Pending => "pending",
|
||||||
};
|
};
|
||||||
let kind = match a.kind {
|
let kind = a.kind.as_str();
|
||||||
hive_sh4re::ApprovalKind::ApplyCommit => "apply_commit",
|
|
||||||
hive_sh4re::ApprovalKind::Spawn => "spawn",
|
|
||||||
hive_sh4re::ApprovalKind::InitConfig => "init_config",
|
|
||||||
hive_sh4re::ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
|
||||||
hive_sh4re::ApprovalKind::SchedulePrompt => "schedule_prompt",
|
|
||||||
hive_sh4re::ApprovalKind::MergeConfigPr => "merge_config_pr",
|
|
||||||
};
|
|
||||||
ApprovalHistoryView {
|
ApprovalHistoryView {
|
||||||
id: a.id,
|
id: a.id,
|
||||||
agent: a.agent,
|
agent: a.agent,
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,24 @@ pub enum ApprovalKind {
|
||||||
MergeConfigPr,
|
MergeConfigPr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApprovalKind {
|
||||||
|
/// Wire/UI string — the same value serde's `snake_case` rename
|
||||||
|
/// produces. The single source of truth for every place that needs
|
||||||
|
/// the kind as a `&'static str` (sqlite storage, dashboard events),
|
||||||
|
/// so adding a variant can't silently miss a hand-rolled match.
|
||||||
|
#[must_use]
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ApprovalKind::ApplyCommit => "apply_commit",
|
||||||
|
ApprovalKind::Spawn => "spawn",
|
||||||
|
ApprovalKind::InitConfig => "init_config",
|
||||||
|
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
||||||
|
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
||||||
|
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ApprovalStatus {
|
pub enum ApprovalStatus {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue