Dispatch to the appropriate inline renderer
(
canonical: &str,
tool_state: &ToolDisplayState,
theme: &Theme,
spinner_frame: &str,
available_width: u16,
)
| 281 | |
| 282 | /// Dispatch to the appropriate inline renderer |
| 283 | fn render_inline_dispatch( |
| 284 | canonical: &str, |
| 285 | tool_state: &ToolDisplayState, |
| 286 | theme: &Theme, |
| 287 | spinner_frame: &str, |
| 288 | available_width: u16, |
| 289 | ) -> ToolCardRenderOutput { |
| 290 | let icon = tool_icon(&tool_state.tool_name); |
| 291 | let is_complete = matches!( |
| 292 | tool_state.status, |
| 293 | ToolDisplayStatus::Success |
| 294 | | ToolDisplayStatus::Failed |
| 295 | | ToolDisplayStatus::Rejected |
| 296 | | ToolDisplayStatus::Cancelled |
| 297 | ); |
| 298 | let is_error = matches!(tool_state.status, ToolDisplayStatus::Failed); |
| 299 | let is_rejected = matches!(tool_state.status, ToolDisplayStatus::Rejected); |
| 300 | let is_confirmation = matches!(tool_state.status, ToolDisplayStatus::ConfirmationNeeded); |
| 301 | |
| 302 | if !is_complete && !is_confirmation { |
| 303 | // Pending state: spinner + pending text |
| 304 | let pending_text = inline_pending_text(canonical, tool_state); |
| 305 | return ToolCardRenderOutput { |
| 306 | items: vec![ListItem::new(Line::from(vec![ |
| 307 | Span::raw(" ".to_string()), |
| 308 | Span::styled( |
| 309 | format!("{} ", spinner_frame), |
| 310 | theme.style(StyleKind::Primary), |
| 311 | ), |
| 312 | Span::styled(pending_text.clone(), theme.style(StyleKind::Muted)), |
| 313 | ]))], |
| 314 | plain_lines: vec![format!(" {} {}", spinner_frame, pending_text)], |
| 315 | }; |
| 316 | } |
| 317 | |
| 318 | // Icon style: independent color for normal, error color for failures |
| 319 | let icon_style = if is_error || is_rejected { |
| 320 | theme.style(StyleKind::Error) |
| 321 | } else if is_confirmation { |
| 322 | theme.style(StyleKind::Warning) |
| 323 | } else { |
| 324 | theme.style(StyleKind::InlineIcon) |
| 325 | }; |
| 326 | |
| 327 | // Content style: muted for completed (consistent with thinking), error for failures |
| 328 | let content_style = if is_error { |
| 329 | theme.style(StyleKind::Error) |
| 330 | } else if is_rejected { |
| 331 | theme |
| 332 | .style(StyleKind::Error) |
| 333 | .add_modifier(Modifier::CROSSED_OUT) |
| 334 | } else if is_confirmation { |
| 335 | theme.style(StyleKind::Warning) |
| 336 | } else { |
| 337 | theme.style(StyleKind::Muted) |
| 338 | }; |
| 339 | |
| 340 | // Display icon: use error icon for failures |
no test coverage detected