-
Notifications
You must be signed in to change notification settings - Fork 17
/
gotable.go
215 lines (192 loc) · 5.82 KB
/
gotable.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package gotable
import (
"encoding/csv"
"encoding/json"
"github.com/liushuochen/gotable/exception"
"github.com/liushuochen/gotable/table"
"github.com/liushuochen/gotable/util"
"io/ioutil"
"os"
"reflect"
"strings"
)
const (
Center = table.C
Left = table.L
Right = table.R
Default = table.Default
)
// Colored display control
const (
TerminalDefault = 0
Highlight = 1
Underline = 4
Flash = 5
)
// Colored control
const (
Black = 30
Red = 31
Green = 32
Yellow = 33
Blue = 34
Purple = 35
Cyan = 36
Write = 37
NoneBackground = 0
)
// Create an empty simple table. When duplicate values in columns, table creation fails.
// It will return a table pointer and an error.
// Error:
// - If the length of columns is not greater than 0, an *exception.ColumnsLengthError error is returned.
// - If columns contain duplicate values, an error is returned.
// - Otherwise, the value of error is nil.
func Create(columns ...string) (*table.Table, error) {
set, err := table.CreateSetFromString(columns...)
if err != nil {
return nil, err
}
tb := table.CreateTable(set)
return tb, nil
}
// CreateSafeTable function used to create an empty safe table. When duplicate values in columns, table creation fails.
// It will return a table pointer and an error.
// Error:
// - If the length of columns is not greater than 0, an *exception.ColumnsLengthError error is returned.
// - If columns contain duplicate values, an error is returned.
// - Otherwise, the value of error is nil.
func CreateSafeTable(columns ...string) (*table.SafeTable, error) {
set, err := table.CreateSetFromString(columns...)
if err != nil {
return nil, err
}
tb := table.CreateSafeTable(set)
return tb, nil
}
// CreateByStruct creates an empty table from struct. You can rename a field using struct tag: gotable
// It will return a table pointer and an error.
// Error:
// - If the length of columns is not greater than 0, an *exception.ColumnsLengthError error is returned.
// - If columns contain duplicate values, an error is returned.
// - Otherwise, the value of error is nil.
func CreateByStruct(v interface{}) (*table.Table, error) {
set := &table.Set{}
s := reflect.TypeOf(v).Elem()
numField := s.NumField()
if numField <= 0 {
return nil, exception.ColumnsLength()
}
for i := 0; i < numField; i++ {
field := s.Field(i)
name := field.Tag.Get("gotable")
if name == "" {
name = field.Name
}
err := set.Add(name)
if err != nil {
return nil, err
}
}
tb := table.CreateTable(set)
return tb, nil
}
// Version
// The version function returns a string representing the version information of the gotable.
// e.g.
//
// gotable 3.4.0
func Version() string {
return "gotable " + strings.Join(getVersions(), ".")
}
// Versions returns a list of version numbers.
func Versions() []string { return getVersions() }
// getVersions 5.18.0
func getVersions() []string {
return []string{"5", "18", "0"}
}
// Read from a csv file to create a *table instance.
// This function is a private function that only called from Read function. It will return a table pointer and an error.
// Error:
// - If the contents of the csv file are empty, an *exception.ColumnsLengthError is returned.
// - If there are duplicate columns in the parse result, an error is returned.
// - Otherwise the value if error is nil.
func readFromCSVFile(file *os.File) (*table.Table, error) {
reader := csv.NewReader(file)
lines, err := reader.ReadAll()
if err != nil {
return nil, err
}
if len(lines) < 1 {
return Create()
}
tb, err := Create(lines[0]...)
if err != nil {
return nil, err
}
rows := make([]map[string]string, 0)
for _, line := range lines[1:] {
row := make(map[string]string)
for i := range line {
row[lines[0][i]] = line[i]
}
rows = append(rows, row)
}
tb.AddRows(rows)
return tb, nil
}
// Read from a json file to create a *table instance.
// This function is a private function that only called from Read function. It will return a table pointer and an error.
// Error:
// - If the contents of the json file are not eligible table contents, an *exception.NotGotableJSONFormatError is
// returned.
// - If there are duplicate columns in the parse result, an error is returned.
// - Otherwise the value if error is nil.
func readFromJSONFile(file *os.File) (*table.Table, error) {
byteValue, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
rows := make([]map[string]string, 0)
err = json.Unmarshal(byteValue, &rows)
if err != nil {
return nil, exception.NotGotableJSONFormat(file.Name())
}
columns := make([]string, 0)
for column := range rows[0] {
columns = append(columns, column)
}
tb, err := Create(columns...)
if err != nil {
return nil, err
}
tb.AddRows(rows)
return tb, nil
}
// Read from file to create a *table instance.
// Currently, support csv and json file. It will return a table pointer and an error.
// Error:
// - If path is not a file, or does not exist, an *exception.FileDoNotExistError is returned.
// - If path is a JSON file, the contents of the file are not eligible table contents, an
// *exception.NotGotableJSONFormatError is returned.
// - If path is a CSV file, and the contents of the file are empty, an *exception.ColumnsLengthError is returned.
// - If there are duplicate columns in the parse result, an error is returned.
// - Otherwise the value if error is nil.
func Read(path string) (*table.Table, error) {
if !util.IsFile(path) {
return nil, exception.FileDoNotExist(path)
}
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer func(file *os.File) {
_ = file.Close()
}(file)
if util.IsJsonFile(file.Name()) {
return readFromJSONFile(file)
}
if util.IsCSVFile(file.Name()) {
return readFromCSVFile(file)
}
return nil, exception.UnSupportedFileType(file.Name())
}