| 226 | } |
| 227 | |
| 228 | func renderHumanTable(title string, headers []string, rows [][]string) string { |
| 229 | var builder strings.Builder |
| 230 | if title != "" { |
| 231 | builder.WriteString(title) |
| 232 | builder.WriteByte('\n') |
| 233 | builder.WriteString(strings.Repeat("=", humanTableCellWidth(title))) |
| 234 | builder.WriteByte('\n') |
| 235 | } |
| 236 | if len(headers) == 0 { |
| 237 | return strings.TrimRight(builder.String(), "\n") |
| 238 | } |
| 239 | |
| 240 | separators := make([]string, 0, len(headers)) |
| 241 | for _, header := range headers { |
| 242 | separators = append(separators, strings.Repeat("-", max(3, humanTableCellWidth(header)))) |
| 243 | } |
| 244 | |
| 245 | tableRows := make([][]string, 0, len(rows)+2) |
| 246 | tableRows = append(tableRows, headers, separators) |
| 247 | if len(rows) == 0 { |
| 248 | tableRows = append(tableRows, []string{"(empty)"}) |
| 249 | } else { |
| 250 | tableRows = append(tableRows, rows...) |
| 251 | } |
| 252 | widths := humanTableColumnWidths(tableRows) |
| 253 | for _, row := range tableRows { |
| 254 | writeHumanTableRow(&builder, row, widths) |
| 255 | } |
| 256 | |
| 257 | return strings.TrimRight(builder.String(), "\n") |
| 258 | } |
| 259 | |
| 260 | func humanTableColumnWidths(rows [][]string) []int { |
| 261 | var widths []int |