#![doc(hidden)] #![expect( clippy::redundant_pub_crate, reason = "this private runtime summary helper only feeds the CLI runtime host and does not define public-facing API contracts" )] use super::{ BtStatusReport, CliError, InProcessRpcDispatcher, dispatcher_status_for_gid, dispatcher_status_summary_for_gid, parse_bt_status_report, rpc_status_text, }; use crate::runtime_planning::RegisteredRuntimeEntry; #[derive(Clone, Debug, Default)] pub(super) struct RuntimeExecutionSummary { pub(super) first_gid: Option, pub(super) tracked_download_count: usize, pub(super) completed_download_count: usize, pub(super) first_status: Option, pub(super) first_total_length: Option, pub(super) first_completed_length: Option, pub(super) first_connections: Option, pub(super) first_bt_status: Option, } pub(super) fn collect_runtime_execution_summary( dispatcher: &mut InProcessRpcDispatcher, entries: &[RegisteredRuntimeEntry], ) -> Result { let mut summary = RuntimeExecutionSummary { first_gid: entries.first().map(|entry| entry.gid.clone()), tracked_download_count: dispatcher.tracked_download_count(), ..RuntimeExecutionSummary::default() }; for (index, entry) in entries.iter().enumerate() { let status = dispatcher_status_summary_for_gid(dispatcher, &entry.gid)?; let status_value = rpc_status_text(status.status); if status.status.as_rpc_status() == "complete" { summary.completed_download_count = summary.completed_download_count.saturating_add(1); } if index == 0 { summary.first_total_length = Some(status.total_length); summary.first_completed_length = Some(status.completed_length); summary.first_connections = Some(status.connections); summary.first_status = Some(status_value); if status.is_bt { let full_status = dispatcher_status_for_gid(dispatcher, &entry.gid)?; summary.first_bt_status = parse_bt_status_report(&full_status); } } } Ok(summary) }