Watch
0
0
Fork
You've already forked hyperhive
0

remove as_str() legacy wrappers, callers use .into() directly

This commit is contained in:
damocles 2026-09-11 21:55:04 +02:00
commit 46456f75ce
25 changed files with 46 additions and 128 deletions

View file

@ -712,7 +712,7 @@ async 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 `Utc::now()`; // approval's logged resolved_at indirectly via `Utc::now()`;
// failures already wrote it via mark_failed above. // failures already wrote it via mark_failed above.
let approval_kind = approval.kind.as_str(); let approval_kind = <&str>::from(approval.kind);
let sha_short = approval let sha_short = approval
.fetched_sha .fetched_sha
.as_deref() .as_deref()
@ -921,7 +921,7 @@ pub fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()> {
tracing::info!(%id, note, "approval denied"); tracing::info!(%id, note, "approval denied");
if let Some(a) = approval { if let Some(a) = approval {
let sha = a.fetched_sha.clone(); let sha = a.fetched_sha.clone();
let approval_kind = a.kind.as_str(); let approval_kind = <&str>::from(a.kind);
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();

View file

@ -55,7 +55,7 @@ pub fn caps_for(name: &str) -> Vec<String> {
pub fn has_cap(name: &str, cap: hive_sh4re::permissions::Capability) -> bool { pub fn has_cap(name: &str, cap: hive_sh4re::permissions::Capability) -> bool {
caps_for(name) caps_for(name)
.iter() .iter()
.any(|s| s.eq_ignore_ascii_case(cap.as_str())) .any(|s| s.eq_ignore_ascii_case(<&str>::from(cap)))
} }
/// Persist the full capability map. Sorted JSON output keeps diffs /// Persist the full capability map. Sorted JSON output keeps diffs

View file

@ -72,7 +72,7 @@ fn write(map: &BTreeMap<String, Vec<String>>) -> std::io::Result<()> {
pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> { pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
let valid: std::collections::BTreeSet<&str> = hive_sh4re::permissions::ToolGroup::ALL let valid: std::collections::BTreeSet<&str> = hive_sh4re::permissions::ToolGroup::ALL
.iter() .iter()
.map(|g| g.as_str()) .map(|g| <&str>::from(*g))
.collect(); .collect();
let unknown: Vec<&str> = groups let unknown: Vec<&str> = groups
.iter() .iter()
@ -87,7 +87,7 @@ pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
unknown.join(", "), unknown.join(", "),
hive_sh4re::permissions::ToolGroup::ALL hive_sh4re::permissions::ToolGroup::ALL
.iter() .iter()
.map(|g| g.as_str()) .map(|g| <&str>::from(*g))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
) )

View file

@ -638,10 +638,10 @@ impl Coordinator {
/// commits the JSON file, so the P3RM1SS10NS tab updates live. /// commits the JSON file, so the P3RM1SS10NS tab updates live.
pub fn emit_capabilities_snapshot(self: &Arc<Self>) { pub fn emit_capabilities_snapshot(self: &Arc<Self>) {
use hive_sh4re::permissions::Capability; use hive_sh4re::permissions::Capability;
let caps = Capability::ALL.iter().map(|c| c.as_str()).collect(); let caps = Capability::ALL.iter().map(|c| <&str>::from(*c)).collect();
let descriptions = Capability::ALL let descriptions = Capability::ALL
.iter() .iter()
.map(|c| (c.as_str(), c.description())) .map(|c| (<&str>::from(*c), c.description()))
.collect(); .collect();
let assignments = crate::capabilities::read(); let assignments = crate::capabilities::read();
// Best-effort roster (sync path); on a contended cache miss we // Best-effort roster (sync path); on a contended cache miss we
@ -665,10 +665,10 @@ impl Coordinator {
/// commits the JSON file, so the P3RM1SS10NS tab updates live. /// commits the JSON file, so the P3RM1SS10NS tab updates live.
pub fn emit_tool_groups_snapshot(self: &Arc<Self>) { pub fn emit_tool_groups_snapshot(self: &Arc<Self>) {
use hive_sh4re::permissions::ToolGroup; use hive_sh4re::permissions::ToolGroup;
let groups = ToolGroup::ALL.iter().map(|g| g.as_str()).collect(); let groups = ToolGroup::ALL.iter().map(|g| <&str>::from(*g)).collect();
let descriptions = ToolGroup::ALL let descriptions = ToolGroup::ALL
.iter() .iter()
.map(|g| (g.as_str(), g.description())) .map(|g| (<&str>::from(*g), g.description()))
.collect(); .collect();
let assignments = crate::tool_groups::read(); let assignments = crate::tool_groups::read();
let roster = self.live_container_names_blocking().unwrap_or_default(); let roster = self.live_container_names_blocking().unwrap_or_default();

View file

@ -105,7 +105,7 @@ pub(super) fn gc_orphans(coord: &Coordinator, approvals: Vec<Approval>) -> Vec<A
coord.emit_approval_resolved(crate::coordinator::ApprovalResolved { coord.emit_approval_resolved(crate::coordinator::ApprovalResolved {
id: a.id, id: a.id,
agent: a.agent.as_str(), agent: a.agent.as_str(),
approval_kind: a.kind.as_str(), approval_kind: <&str>::from(a.kind),
sha_short, sha_short,
status: "failed", status: "failed",
note: Some(note.to_owned()), note: Some(note.to_owned()),

View file

@ -50,11 +50,11 @@ pub(super) async fn get_tool_groups(
) -> axum::Json<ToolGroupsSnapshot> { ) -> axum::Json<ToolGroupsSnapshot> {
let groups = hive_sh4re::permissions::ToolGroup::ALL let groups = hive_sh4re::permissions::ToolGroup::ALL
.iter() .iter()
.map(|g| g.as_str()) .map(|g| <&str>::from(*g))
.collect(); .collect();
let descriptions = hive_sh4re::permissions::ToolGroup::ALL let descriptions = hive_sh4re::permissions::ToolGroup::ALL
.iter() .iter()
.map(|g| (g.as_str(), g.description())) .map(|g| (<&str>::from(*g), g.description()))
.collect(); .collect();
let assignments = crate::tool_groups::read(); let assignments = crate::tool_groups::read();
let roster = state let roster = state
@ -82,7 +82,7 @@ pub(super) async fn get_tool_groups(
pub(crate) fn tool_group_default_names() -> Vec<&'static str> { pub(crate) fn tool_group_default_names() -> Vec<&'static str> {
hive_sh4re::permissions::ToolGroup::AGENT_DEFAULT hive_sh4re::permissions::ToolGroup::AGENT_DEFAULT
.iter() .iter()
.map(|g| g.as_str()) .map(|g| <&str>::from(*g))
.collect() .collect()
} }
@ -205,10 +205,10 @@ pub(super) async fn get_capabilities(
State(state): State<AppState>, State(state): State<AppState>,
) -> axum::Json<CapabilitiesSnapshot> { ) -> axum::Json<CapabilitiesSnapshot> {
use hive_sh4re::permissions::Capability; use hive_sh4re::permissions::Capability;
let caps = Capability::ALL.iter().map(|c| c.as_str()).collect(); let caps = Capability::ALL.iter().map(|c| <&str>::from(*c)).collect();
let descriptions = Capability::ALL let descriptions = Capability::ALL
.iter() .iter()
.map(|c| (c.as_str(), c.description())) .map(|c| (<&str>::from(*c), c.description()))
.collect(); .collect();
let assignments = crate::capabilities::read(); let assignments = crate::capabilities::read();
let roster = state let roster = state
@ -258,7 +258,7 @@ pub(super) async fn post_capabilities(
} }
let known: Vec<&str> = hive_sh4re::permissions::Capability::ALL let known: Vec<&str> = hive_sh4re::permissions::Capability::ALL
.iter() .iter()
.map(|c| c.as_str()) .map(|c| <&str>::from(*c))
.collect(); .collect();
for cap in &body.caps { for cap in &body.caps {
if !known.contains(&cap.as_str()) { if !known.contains(&cap.as_str()) {
@ -336,7 +336,7 @@ pub(super) async fn post_permissions(
) -> Result<Response, ProblemDetails> { ) -> Result<Response, ProblemDetails> {
let known_caps: Vec<&str> = hive_sh4re::permissions::Capability::ALL let known_caps: Vec<&str> = hive_sh4re::permissions::Capability::ALL
.iter() .iter()
.map(|c| c.as_str()) .map(|c| <&str>::from(*c))
.collect(); .collect();
// Phase 1 — validate everything before touching any file or the // Phase 1 — validate everything before touching any file or the
// queue, so a bad entry fails the whole POST with zero side effects. // queue, so a bad entry fails the whole POST with zero side effects.

View file

@ -423,7 +423,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::approvals::ApprovalStatus::Pending => "pending", hive_sh4re::approvals::ApprovalStatus::Pending => "pending",
}; };
let kind = a.kind.as_str(); let kind = <&str>::from(a.kind);
ApprovalHistoryView { ApprovalHistoryView {
id: a.id, id: a.id,
agent: a.agent.to_string(), agent: a.agent.to_string(),

View file

@ -385,7 +385,7 @@ fn run_set_wanted(coord: &Arc<Coordinator>, agent: &str, up: bool) -> Result<()>
coord coord
.power .power
.set(agent, wanted) .set(agent, wanted)
.with_context(|| format!("set wanted={} for agent {agent}", wanted.as_str()))?; .with_context(|| format!("set wanted={} for agent {agent}", <&str>::from(wanted)))?;
Ok(()) Ok(())
} }
@ -579,7 +579,7 @@ async fn run_reconcile(coord: &Arc<Coordinator>, name: &str) -> Result<Option<No
agent: name.to_owned(), agent: name.to_owned(),
}), }),
ReconcileAction::Noop => { ReconcileAction::Noop => {
tracing::debug!(%name, wanted = wanted.as_str(), running, "reconcile: noop"); tracing::debug!(%name, wanted = <&str>::from(wanted), running, "reconcile: noop");
None None
} }
}) })

View file

@ -313,7 +313,7 @@ impl JobQueue {
} }
Some(RunningTransient { Some(RunningTransient {
agent: agent.to_owned(), agent: agent.to_owned(),
label: n.payload.as_str().to_owned(), label: <&str>::from(&n.payload).to_owned(),
takes_container_down: n.payload.takes_container_down(), takes_container_down: n.payload.takes_container_down(),
// `started_at` is set when a node enters `Running`, and this // `started_at` is set when a node enters `Running`, and this
// only sees `Running` nodes — the fallback is unreachable in // only sees `Running` nodes — the fallback is unreachable in

View file

@ -170,7 +170,7 @@ pub enum NodeKind {
/// renders it without knowing what any of it means. /// renders it without knowing what any of it means.
impl hive_jobq_wire::WireNode for NodeKind { impl hive_jobq_wire::WireNode for NodeKind {
fn label(&self) -> String { fn label(&self) -> String {
self.as_str().to_owned() <&str>::from(self).to_owned()
} }
fn data(&self, id: hive_jobq_wire::WireId) -> serde_json::Value { fn data(&self, id: hive_jobq_wire::WireId) -> serde_json::Value {
@ -201,16 +201,6 @@ impl hive_jobq_wire::WireNode for NodeKind {
} }
impl NodeKind { impl NodeKind {
/// Wire string for the node's label on the graph wire
/// ([`hive_jobq_wire::WireNode::label`]) — derived
/// (`#[strum(serialize_all = "snake_case")]`), matching the same
/// convention the `#[serde(rename_all = "snake_case")]` tag above
/// uses, rather than a 31-arm hand-written match kept in sync with it
/// by hand.
pub fn as_str(&self) -> &'static str {
self.into()
}
/// The agent this node targets, or `""` for agentless kinds /// The agent this node targets, or `""` for agentless kinds
/// ([`NodeKind::MetaLock`] on the `hyperhive` pseudo-agent, /// ([`NodeKind::MetaLock`] on the `hyperhive` pseudo-agent,
/// [`NodeKind::Reparent`] which can span multiple agents, and /// [`NodeKind::Reparent`] which can span multiple agents, and

View file

@ -92,10 +92,11 @@ pub async fn run_worker(coord: Arc<Coordinator>) {
hive_jobq::scheduler::Scheduler::claim_next(&sched, move |id, kind, builder| { hive_jobq::scheduler::Scheduler::claim_next(&sched, move |id, kind, builder| {
let coord = node_coord; let coord = node_coord;
async move { async move {
let kind_str = <&str>::from(&kind);
tracing::info!( tracing::info!(
dag = coord.job_queue.root_of(id).unwrap_or_default(), dag = coord.job_queue.root_of(id).unwrap_or_default(),
node = id.get(), node = id.get(),
kind = kind.as_str(), kind = kind_str,
agent = %kind.agent(), agent = %kind.agent(),
"job_queue: node running" "job_queue: node running"
); );
@ -104,7 +105,7 @@ pub async fn run_worker(coord: Arc<Coordinator>) {
Ok(()) => tracing::info!(node = id.get(), "job_queue: node done"), Ok(()) => tracing::info!(node = id.get(), "job_queue: node done"),
Err(e) => tracing::warn!( Err(e) => tracing::warn!(
node = id.get(), node = id.get(),
kind = kind.as_str(), kind = kind_str,
agent = %kind.agent(), agent = %kind.agent(),
error = %format!("{e:#}"), error = %format!("{e:#}"),
grown_nodes = !grown.is_empty(), grown_nodes = !grown.is_empty(),

View file

@ -862,7 +862,7 @@ fn rebuild_chain_nodes_suppress_crash_watch() {
kind.takes_container_down(), kind.takes_container_down(),
"{} must suppress crash-watch — a rebuild takes the container down \ "{} must suppress crash-watch — a rebuild takes the container down \
on purpose", on purpose",
kind.as_str() <&str>::from(&kind)
); );
} }
// The counter-case, and the reason this can't be "any node in a rebuild": // The counter-case, and the reason this can't be "any node in a rebuild":

View file

@ -823,7 +823,7 @@ fn handle_cancel_loose_end(
coord.emit_approval_resolved(crate::coordinator::ApprovalResolved { coord.emit_approval_resolved(crate::coordinator::ApprovalResolved {
id: approval.id, id: approval.id,
agent: approval.agent.as_str(), agent: approval.agent.as_str(),
approval_kind: approval.kind.as_str(), approval_kind: <&str>::from(approval.kind),
sha_short, sha_short,
status: "cancelled", status: "cancelled",
note: approval.note, note: approval.note,

View file

@ -93,7 +93,7 @@ impl Approvals {
VALUES (?1, ?2, ?3, ?4, 'pending', ?5, ?6, ?7)", VALUES (?1, ?2, ?3, ?4, 'pending', ?5, ?6, ?7)",
params![ params![
agent, agent,
kind.as_str(), <&str>::from(kind),
commit_ref, commit_ref,
Utc::now().timestamp(), Utc::now().timestamp(),
description, description,

View file

@ -100,12 +100,6 @@ pub enum BuildStatus {
Fail, Fail,
} }
impl BuildStatus {
fn as_str(self) -> &'static str {
self.into()
}
}
/// Header-only row returned by `list_recent_for_agent`. Carries the /// Header-only row returned by `list_recent_for_agent`. Carries the
/// metadata the dashboard's agent-card chip needs (status + age + /// metadata the dashboard's agent-card chip needs (status + age +
/// id-to-open) without the multi-MB stdout/stderr payload. /// id-to-open) without the multi-MB stdout/stderr payload.
@ -278,7 +272,7 @@ impl BuildLogs {
let conn = self.conn.lock().unwrap(); let conn = self.conn.lock().unwrap();
if let Err(e) = conn.execute( if let Err(e) = conn.execute(
"UPDATE build_logs SET finished_at = ?1, status = ?2 WHERE id = ?3", "UPDATE build_logs SET finished_at = ?1, status = ?2 WHERE id = ?3",
params![now, status.as_str(), id], params![now, <&str>::from(status), id],
) { ) {
tracing::warn!( tracing::warn!(
build_log_id = id, build_log_id = id,

View file

@ -38,10 +38,6 @@ pub enum Wanted {
} }
impl Wanted { impl Wanted {
pub fn as_str(self) -> &'static str {
self.into()
}
/// Derived (`strum::EnumString`, the same `snake_case` convention /// Derived (`strum::EnumString`, the same `snake_case` convention
/// `as_str` uses) rather than a hand-written match kept in sync with /// `as_str` uses) rather than a hand-written match kept in sync with
/// it by hand. /// it by hand.
@ -138,7 +134,7 @@ impl PowerStore {
conn.execute( conn.execute(
"INSERT INTO agent_power (agent, wanted, updated_at) VALUES (?1, ?2, ?3) "INSERT INTO agent_power (agent, wanted, updated_at) VALUES (?1, ?2, ?3)
ON CONFLICT(agent) DO UPDATE SET wanted = ?2, updated_at = ?3", ON CONFLICT(agent) DO UPDATE SET wanted = ?2, updated_at = ?3",
params![agent, wanted.as_str(), Utc::now().timestamp()], params![agent, <&str>::from(wanted), Utc::now().timestamp()],
) )
.context("upsert agent_power")?; .context("upsert agent_power")?;
Ok(()) Ok(())
@ -154,7 +150,7 @@ impl PowerStore {
} }
let seeded = Wanted::from_running(running); let seeded = Wanted::from_running(running);
self.set(agent, seeded)?; self.set(agent, seeded)?;
tracing::info!(%agent, wanted = seeded.as_str(), "agent_power: seeded from observed state"); tracing::info!(%agent, wanted = <&str>::from(seeded), "agent_power: seeded from observed state");
Ok(seeded) Ok(seeded)
} }

View file

@ -173,7 +173,7 @@ fn seed_manager_tool_groups() {
} }
let all_groups: Vec<String> = hive_sh4re::permissions::ToolGroup::MANAGER_DEFAULT let all_groups: Vec<String> = hive_sh4re::permissions::ToolGroup::MANAGER_DEFAULT
.iter() .iter()
.map(|g| g.as_str().to_owned()) .map(|g| <&str>::from(*g).to_owned())
.collect(); .collect();
match tool_groups::set_groups(MANAGER_NAME, &all_groups) { match tool_groups::set_groups(MANAGER_NAME, &all_groups) {
Ok(()) => tracing::info!("seeded ruth's tool groups to MANAGER_DEFAULT (all groups)"), Ok(()) => tracing::info!("seeded ruth's tool groups to MANAGER_DEFAULT (all groups)"),

View file

@ -21,12 +21,6 @@ pub enum StateArg {
Closed, Closed,
} }
impl StateArg {
fn as_str(self) -> &'static str {
self.into()
}
}
#[derive(ClapArgs)] #[derive(ClapArgs)]
pub struct Args { pub struct Args {
/// Issue (or PR — shares the same `/issues/<n>` endpoint) number. /// Issue (or PR — shares the same `/issues/<n>` endpoint) number.
@ -74,7 +68,7 @@ pub fn run(client: &Client, args: Args) -> Result<()> {
due_date: None, due_date: None,
milestone: args.milestone.map(index).transpose()?, milestone: args.milestone.map(index).transpose()?,
r#ref: None, r#ref: None,
state: args.state.map(|s| s.as_str().to_owned()), state: args.state.map(|s| <&str>::from(s).to_owned()),
title: args.title, title: args.title,
unset_due_date: None, unset_due_date: None,
updated_at: None, updated_at: None,

View file

@ -71,17 +71,6 @@ pub enum ApprovalKind {
MergeConfigPr, MergeConfigPr,
} }
impl ApprovalKind {
/// Wire/UI string — the same value serde's `snake_case` rename
/// produces, via the same derive (`#[strum(serialize_all =
/// "snake_case")]`) rather than a hand-rolled match a new variant
/// could silently miss.
#[must_use]
pub fn as_str(self) -> &'static str {
self.into()
}
}
#[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 {

View file

@ -154,15 +154,6 @@ impl ToolGroup {
Self::WebTools, Self::WebTools,
]; ];
/// The `snake_case` wire name for this group (matches `serde(rename_all =
/// "snake_case")` serialisation) — derived (`#[strum(serialize_all =
/// "snake_case")]`) from the same convention rather than a hand-written
/// match kept in sync with it by hand.
#[must_use]
pub fn as_str(self) -> &'static str {
self.into()
}
/// Short human-readable description suitable for a tooltip or help text. /// Short human-readable description suitable for a tooltip or help text.
#[must_use] #[must_use]
pub fn description(self) -> &'static str { pub fn description(self) -> &'static str {
@ -240,14 +231,6 @@ impl Capability {
Self::QueryAgentState, Self::QueryAgentState,
]; ];
/// Canonical `snake_case` name for this capability (matches serde) —
/// derived rather than a hand-written match, same as
/// [`ToolGroup::as_str`].
#[must_use]
pub fn as_str(self) -> &'static str {
self.into()
}
/// Short human-readable description suitable for a tooltip or help text. /// Short human-readable description suitable for a tooltip or help text.
#[must_use] #[must_use]
pub fn description(self) -> &'static str { pub fn description(self) -> &'static str {

Some files were not shown because too many files have changed in this diff Show more