mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package colprint
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// formatFn is a function that converts a value of type T to its string representation
|
|
type formatFn[T any] func(T) (string, error)
|
|
|
|
// PrintColumns prints values in columns, adapting to long values by letting them span multiple columns
|
|
func PrintColumns[T any](values <-chan T, numCols int, sampleSize int, format formatFn[T], w io.Writer) error {
|
|
// Get first batch and determine column width
|
|
maxLen := 0
|
|
var samples []T
|
|
|
|
for v := range values {
|
|
samples = append(samples, v)
|
|
str, err := format(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(str) > maxLen {
|
|
maxLen = len(str)
|
|
}
|
|
if len(samples) >= sampleSize {
|
|
break
|
|
}
|
|
}
|
|
|
|
colWidth := maxLen + 2 // Add minimum padding
|
|
if colWidth < 1 {
|
|
colWidth = 1
|
|
}
|
|
|
|
// Print in columns using our determined width
|
|
col := 0
|
|
for _, v := range samples {
|
|
str, err := format(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := printColHelper(str, colWidth, &col, numCols, w); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Continue with any remaining values
|
|
for v := range values {
|
|
str, err := format(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := printColHelper(str, colWidth, &col, numCols, w); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if col > 0 {
|
|
if _, err := fmt.Fprint(w, "\n"); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func printColHelper(str string, colWidth int, col *int, numCols int, w io.Writer) error {
|
|
nameColSpan := (len(str) + 1) / colWidth
|
|
if (len(str)+1)%colWidth != 0 {
|
|
nameColSpan++
|
|
}
|
|
|
|
if *col+nameColSpan > numCols {
|
|
if _, err := fmt.Fprint(w, "\n"); err != nil {
|
|
return err
|
|
}
|
|
*col = 0
|
|
}
|
|
|
|
if _, err := fmt.Fprintf(w, "%-*s", nameColSpan*colWidth, str); err != nil {
|
|
return err
|
|
}
|
|
*col += nameColSpan
|
|
return nil
|
|
}
|