diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2018-09-17 21:02:30 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2018-09-17 21:02:30 +1000 |
commit | c00c834b359bc0ebcd6e940e5cb5ef6f7247a6c7 (patch) | |
tree | 67ca05580afab38e8a743d6c3fcf91caa1cf82ee /pkg/utils | |
parent | 3b765e5417501a39bca5c2f0038488dbbeb6b200 (diff) |
standardise rendering of lists in panels
Diffstat (limited to 'pkg/utils')
-rw-r--r-- | pkg/utils/utils.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index cb23eb75e..f1a56116b 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,10 +1,12 @@ package utils import ( + "errors" "fmt" "log" "os" "path/filepath" + "reflect" "strings" "time" @@ -107,3 +109,67 @@ func Min(x, y int) int { } return y } + +type Displayable interface { + GetDisplayStrings() []string +} + +// RenderList takes a slice of items, confirms they implement the Displayable +// interface, then generates a list of their displaystrings to write to a panel's +// buffer +func RenderList(slice interface{}) (string, error) { + s := reflect.ValueOf(slice) + if s.Kind() != reflect.Slice { + return "", errors.New("RenderList given a non-slice type") + } + + displayables := make([]Displayable, s.Len()) + + for i := 0; i < s.Len(); i++ { + value, ok := s.Index(i).Interface().(Displayable) + if !ok { + return "", errors.New("item does not implement the Displayable interface") + } + displayables[i] = value + } + + return renderDisplayableList(displayables) +} + +// renderDisplayableList takes a list of displayable items, obtains their display +// strings via GetDisplayStrings() and then returns a single string containing +// each item's string representation on its own line, with appropriate horizontal +// padding between the item's own strings +func renderDisplayableList(items []Displayable) (string, error) { + displayStrings := make([][]string, len(items)) + + for i, item := range items { + displayStrings[i] = item.GetDisplayStrings() + } + + if len(displayStrings) == 0 { + return "", nil + } + + // use first element to determine how many times to do this + padWidths := make([]int, len(displayStrings[0])) + for i, _ := range padWidths { + for _, strings := range displayStrings { + if len(strings) != len(padWidths) { + return "", errors.New("Each item must return the same number of strings to display") + } + if len(strings[i]) > padWidths[i] { + padWidths[i] = len(strings[i]) + } + } + } + + paddedDisplayStrings := make([]string, len(displayStrings)) + for i, strings := range displayStrings { + for j, padWidth := range padWidths { + paddedDisplayStrings[i] += WithPadding(strings[j], padWidth) + " " + } + } + + return strings.Join(paddedDisplayStrings, "\n"), nil +} |