Skip to content

Commit ebe42c2

Browse files
author
Massimiliano Pippi
committed
restore table module
1 parent a64e901 commit ebe42c2

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed

cli/output/table.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* This file is part of arduino-cli.
3+
*
4+
* Copyright 2018 ARDUINO SA (http://www.arduino.cc/)
5+
*
6+
* This software is released under the GNU General Public License version 3,
7+
* which covers the main part of arduino-cli.
8+
* The terms of this license can be found at:
9+
* https://www.gnu.org/licenses/gpl-3.0.en.html
10+
*
11+
* You can be released from the requirements of the above licenses by purchasing
12+
* a commercial license. Buying such a license is mandatory if you want to modify or
13+
* otherwise use the software for commercial activities involving the Arduino
14+
* software without disclosing the source code of your own applications. To purchase
15+
* a commercial license, send an email to license@arduino.cc.
16+
*/
17+
18+
package output
19+
20+
import (
21+
"fmt"
22+
"math"
23+
)
24+
25+
// Table FIXMEDOC
26+
type Table struct {
27+
hasHeader bool
28+
columnsCount int
29+
columnsWidthMode []TableColumnWidthMode
30+
rows []*TableRow
31+
}
32+
33+
// TableRow FIXMEDOC
34+
type TableRow struct {
35+
cells []TextBox
36+
}
37+
38+
// NewTable FIXMEDOC
39+
func NewTable() *Table {
40+
return &Table{
41+
rows: []*TableRow{},
42+
}
43+
}
44+
45+
// TableColumnWidthMode FIXMEDOC
46+
type TableColumnWidthMode int
47+
48+
const (
49+
// Minimum FIXMEDOC
50+
Minimum TableColumnWidthMode = iota
51+
// Average FIXMEDOC
52+
Average
53+
)
54+
55+
// SetColumnWidthMode FIXMEDOC
56+
func (t *Table) SetColumnWidthMode(x int, mode TableColumnWidthMode) {
57+
for len(t.columnsWidthMode) <= x {
58+
t.columnsWidthMode = append(t.columnsWidthMode, Minimum)
59+
}
60+
t.columnsWidthMode[x] = mode
61+
}
62+
63+
func (t *Table) makeTableRow(columns ...interface{}) *TableRow {
64+
columnsCount := len(columns)
65+
if t.columnsCount < columnsCount {
66+
t.columnsCount = columnsCount
67+
}
68+
cells := make([]TextBox, columnsCount)
69+
for i, col := range columns {
70+
switch text := col.(type) {
71+
case TextBox:
72+
cells[i] = text
73+
case string:
74+
cells[i] = sprintf("%s", text)
75+
case fmt.Stringer:
76+
cells[i] = sprintf("%s", text.String())
77+
default:
78+
panic(fmt.Sprintf("invalid column argument type: %t", col))
79+
}
80+
}
81+
return &TableRow{cells: cells}
82+
}
83+
84+
// SetHeader FIXMEDOC
85+
func (t *Table) SetHeader(columns ...interface{}) {
86+
row := t.makeTableRow(columns...)
87+
if t.hasHeader {
88+
t.rows[0] = row
89+
} else {
90+
t.rows = append([]*TableRow{row}, t.rows...)
91+
t.hasHeader = true
92+
}
93+
}
94+
95+
// AddRow FIXMEDOC
96+
func (t *Table) AddRow(columns ...interface{}) {
97+
row := t.makeTableRow(columns...)
98+
t.rows = append(t.rows, row)
99+
}
100+
101+
// Render FIXMEDOC
102+
func (t *Table) Render() string {
103+
// find max width for each row
104+
average := make([]int, t.columnsCount)
105+
widths := make([]int, t.columnsCount)
106+
count := make([]int, t.columnsCount)
107+
for _, row := range t.rows {
108+
for x, cell := range row.cells {
109+
l := cell.Len()
110+
if l == 0 {
111+
continue
112+
}
113+
count[x]++
114+
average[x] += l
115+
if cell.Len() > widths[x] {
116+
widths[x] = l
117+
}
118+
}
119+
}
120+
for x := range average {
121+
if count[x] > 0 {
122+
average[x] = average[x] / count[x]
123+
}
124+
}
125+
variance := make([]int, t.columnsCount)
126+
for _, row := range t.rows {
127+
for x, cell := range row.cells {
128+
l := cell.Len()
129+
if l == 0 {
130+
continue
131+
}
132+
d := l - average[x]
133+
variance[x] += d * d
134+
}
135+
}
136+
for x := range variance {
137+
if count[x] > 0 {
138+
variance[x] = int(math.Sqrt(float64(variance[x] / count[x])))
139+
}
140+
}
141+
142+
res := ""
143+
for _, row := range t.rows {
144+
separator := ""
145+
for x, cell := range row.cells {
146+
selectedWidth := widths[x]
147+
if x < len(t.columnsWidthMode) {
148+
switch t.columnsWidthMode[x] {
149+
case Minimum:
150+
selectedWidth = widths[x]
151+
case Average:
152+
selectedWidth = average[x] + variance[x]*3
153+
}
154+
}
155+
res += separator
156+
res += cell.Pad(selectedWidth)
157+
separator = " "
158+
}
159+
res += "\n"
160+
}
161+
return res
162+
}

0 commit comments

Comments
 (0)