/
text.go
95 lines (81 loc) · 1.83 KB
/
text.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
package formatter
import (
"fmt"
"io"
"reflect"
"sort"
"strings"
)
const delimiter = "\t"
type Text struct {
writer io.Writer
}
func (f *Text) Write(o interface{}) {
f.writeValue(reflect.ValueOf(o))
}
func (f *Text) writeValue(value reflect.Value) {
switch value.Kind() {
case reflect.Struct:
f.writeStruct(value)
case reflect.Ptr:
f.writeValue(value.Elem())
case reflect.Slice:
f.writeSliceValue(value)
default:
f.writeOther(value)
}
}
func (f *Text) writeOther(value reflect.Value) {
f.write(value)
f.newLine()
}
func (f *Text) writeSliceValue(sliceValue reflect.Value) {
for i := 0; i < sliceValue.Len(); i++ {
itemValue := sliceValue.Index(i)
f.writeValue(itemValue)
}
}
func (f *Text) writeStruct(value reflect.Value) {
f.writeSimpleFields(value)
f.writeCompoundFields(value)
}
func (f *Text) writeSimpleFields(value reflect.Value) {
id := strings.ToUpper(value.Type().Name())
f.write(id)
fieldNames := getFieldNames(value)
for _, fieldName := range fieldNames {
field := value.FieldByName(fieldName)
if isSimpleType(field) {
f.write(delimiter)
f.write(fmt.Sprint(field))
}
}
f.newLine()
}
func isSimpleType(value reflect.Value) bool {
return !(value.Kind() == reflect.Struct || value.Kind() == reflect.Slice)
}
func (f *Text) write(v interface{}) {
_, _ = fmt.Fprint(f.writer, v)
}
func (f *Text) newLine() {
_, _ = fmt.Fprintln(f.writer)
}
func getFieldNames(value reflect.Value) []string {
var names []string
valueType := value.Type()
for i := 0; i < value.NumField(); i++ {
names = append(names, valueType.Field(i).Name)
}
sort.Strings(names)
return names
}
func (f *Text) writeCompoundFields(value reflect.Value) {
fieldNames := getFieldNames(value)
for _, fieldName := range fieldNames {
field := value.FieldByName(fieldName)
if !isSimpleType(field) {
f.writeValue(field)
}
}
}