forked from sensu/sensu-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.go
156 lines (132 loc) · 3.08 KB
/
list.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package list
import (
"fmt"
"io"
"strings"
"github.com/sensu/sensu-go/cli/elements/globals"
padUtf8 "github.com/willf/pad/utf8"
)
// StrTransform .. use to transform values; typically used to apply unicode colors to cells
type StrTransform func(string) string
// Config describes detail list
type Config struct {
// Title that is displayed for the list of details
Title string
// TitleStyle formats the title; optional.
TitleStyle StrTransform
// RowFormatter transforms /all/ rows; optional.
RowFormatter StrTransform
// LabelStyle formats the name; optional.
LabelStyle StrTransform
// Rows describes all rows to display
Rows []*Row
}
// Row of data to display
type Row struct {
// Label of the row
Label string
// Value to display
Value string
}
// Print (s) out details list given configuration data
func Print(out io.Writer, cfg *Config) error {
listElem := newListElem(cfg)
return listElem.write(out)
}
type listElem struct {
title string
titleStyle StrTransform
rows []*rowElem
}
type rowElem struct {
label string
labelStyle StrTransform
labelMemo string
value string
valueFormatter StrTransform
}
func newListElem(cfg *Config) listElem {
writer := listElem{
title: cfg.Title,
titleStyle: cfg.TitleStyle,
}
for _, row := range cfg.Rows {
writer.rows = append(writer.rows, &rowElem{
label: row.Label,
labelStyle: cfg.LabelStyle,
value: row.Value,
valueFormatter: cfg.RowFormatter,
})
}
return writer
}
func (e *listElem) write(out io.Writer) error {
if err := e.writeTitle(out); err != nil {
return err
}
return e.writeRows(out)
}
func (e *listElem) writeTitle(out io.Writer) error {
transformer := defaultTitleStyle
if e.titleStyle != nil {
transformer = e.titleStyle
}
_, err := fmt.Fprintln(out, transformer(e.title))
return err
}
func (e *listElem) writeRows(out io.Writer) error {
labelLen := e.longestLabel()
for _, row := range e.rows {
if err := row.write(out, labelLen); err != nil {
return err
}
}
return nil
}
func (e *listElem) longestLabel() (max int) {
for _, row := range e.rows {
len := row.labelLen()
if len > max {
max = len
}
}
return
}
func (e *rowElem) write(out io.Writer, len int) error {
_, err := fmt.Fprintf(
out,
"%s%s\n",
padUtf8.Right(e.styledLabel(), len, " "),
e.formattedValue(),
)
return err
}
func (e *rowElem) styleLabel() string {
if e.labelStyle != nil {
return e.labelStyle(e.label)
}
return defaultLabelStyle(e.label)
}
func (e *rowElem) styledLabel() string {
if e.labelMemo == "" {
e.labelMemo = e.styleLabel()
}
return e.labelMemo
}
func (e *rowElem) labelLen() int {
return len(e.styledLabel())
}
func (e *rowElem) formattedValue() string {
if e.valueFormatter != nil {
return e.valueFormatter(e.value)
}
return e.value
}
// sets the title to bold and prepends '==='
func defaultTitleStyle(title string) string {
return fmt.Sprintf("=== %s", globals.TitleStyle(title))
}
// appends a colon and a space
func defaultLabelStyle(name string) string {
return fmt.Sprintf("%s: ", strings.Title(name))
}