Render a single structured log line — no target, smart field order, truncated.
(log: &'a LogLine, max_width: usize, t: &'a crate::theme::Theme)
| 210 | |
| 211 | /// Render a single structured log line — no target, smart field order, truncated. |
| 212 | fn render_log_line<'a>(log: &'a LogLine, max_width: usize, t: &'a crate::theme::Theme) -> Line<'a> { |
| 213 | let source_style = match log.source.as_str() { |
| 214 | "sandbox" => t.accent, |
| 215 | _ => t.muted, |
| 216 | }; |
| 217 | |
| 218 | let ts = format_short_time(log.timestamp_ms); |
| 219 | |
| 220 | let mut spans = vec![ |
| 221 | Span::styled(ts, t.muted), |
| 222 | Span::raw(" "), |
| 223 | Span::styled(format!("{:<7}", log.source), source_style), |
| 224 | Span::raw(" "), |
| 225 | Span::styled(format!("{:<5}", log.level), level_style(&log.level, t)), |
| 226 | Span::raw(" "), |
| 227 | ]; |
| 228 | |
| 229 | // Message. |
| 230 | spans.push(Span::styled(log.message.as_str(), t.text)); |
| 231 | |
| 232 | // Structured fields — ordered, non-empty only. |
| 233 | if !log.fields.is_empty() { |
| 234 | let ordered = ordered_fields(log); |
| 235 | for (k, v) in &ordered { |
| 236 | if v.is_empty() { |
| 237 | continue; |
| 238 | } |
| 239 | spans.push(Span::raw(" ")); |
| 240 | spans.push(Span::styled(format!("{k}="), t.muted)); |
| 241 | spans.push(Span::styled((*v).to_string(), t.text)); |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | // Truncate to max_width. |
| 246 | truncate_line(spans, max_width, t) |
| 247 | } |
| 248 | |
| 249 | /// Truncate a span list to fit within `max_width` characters, appending `…` if needed. |
| 250 | fn truncate_line<'a>( |
no test coverage detected