diff --git a/putils/README.md b/putils/README.md index 8272f04d2..38d030cf1 100644 --- a/putils/README.md +++ b/putils/README.md @@ -14,4 +14,6 @@ func DownloadFileWithDefaultProgressbar(title, outputPath, url string, mode os.F func DownloadFileWithProgressbar(progressbar *pterm.ProgressbarPrinter, outputPath, url string, mode os.FileMode) error func RunWithDefaultSpinner(initzialSpinnerText string, f func(spinner *pterm.SpinnerPrinter) error) error func RunWithSpinner(spinner *pterm.SpinnerPrinter, f func(spinner *pterm.SpinnerPrinter) error) error +func DefaultTableFromStructSlice(structSlice interface{}) *pterm.TablePrinter +func TableFromStructSlice(tablePrinter pterm.TablePrinter, structSlice interface{}) *pterm.TablePrinter ``` diff --git a/putils/table-from-struct-slice.go b/putils/table-from-struct-slice.go new file mode 100644 index 000000000..dd9a103d5 --- /dev/null +++ b/putils/table-from-struct-slice.go @@ -0,0 +1,71 @@ +package putils + +import ( + "reflect" + + "github.com/pterm/pterm" +) + +// TableFromStructSlice accepts a customized table printer and and a slice of a struct. +// The table will be populated with the values of the structs. The header will be set to the structs field name. +// Use .WithHasHeader() to color the header. +// The function will return the populated pterm.TablePrinter. +func TableFromStructSlice(tablePrinter pterm.TablePrinter, structSlice interface{}) *pterm.TablePrinter { + to := reflect.TypeOf(structSlice) + if to.Kind() != reflect.Slice { + return &tablePrinter + } + el := to.Elem() + + isPointer := false + if el.Kind() == reflect.Ptr { + el = el.Elem() + isPointer = true + } + + if el.Kind() != reflect.Struct { + return &tablePrinter + } + + numFields := el.NumField() + fieldNames := make([]string, numFields) + + for i := 0; i < numFields; i++ { + fieldNames[i] = el.Field(i).Name + } + + records := pterm.TableData{ + fieldNames, + } + + obj := reflect.ValueOf(structSlice) + + items := make([]interface{}, obj.Len()) + for i := 0; i < obj.Len(); i++ { + if isPointer { + items[i] = obj.Index(i).Elem().Interface() + } else { + items[i] = obj.Index(i).Interface() + } + } + + for _, v := range items { + item := reflect.ValueOf(v) + record := make([]string, numFields) + for i := 0; i < numFields; i++ { + fieldVal := item.Field(i).Interface() + record[i] = pterm.Sprintf("%v", fieldVal) + } + records = append(records, record) + } + tablePrinter.Data = records + + return &tablePrinter +} + +// DefaultTableFromStructSlice will be populate the pterm.DefaultTable with the values of the structs. The header will be set to the structs field name. +// Use .WithHasHeader() to color the header. +// The function will return the populated pterm.TablePrinter. +func DefaultTableFromStructSlice(structSlice interface{}) *pterm.TablePrinter { + return TableFromStructSlice(pterm.DefaultTable, structSlice) +} diff --git a/table_printer_test.go b/table_printer_test.go index 123f7caf3..6f4aa3d12 100644 --- a/table_printer_test.go +++ b/table_printer_test.go @@ -2,9 +2,10 @@ package pterm import ( "encoding/csv" - "github.com/stretchr/testify/assert" "os" "testing" + + "github.com/stretchr/testify/assert" ) func TestTablePrinter_NilPrint(t *testing.T) {