-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcell_type.go
More file actions
150 lines (136 loc) · 3.43 KB
/
Copy pathcell_type.go
File metadata and controls
150 lines (136 loc) · 3.43 KB
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
package goods
import (
"fmt"
"strconv"
"time"
)
// CellType identifies the semantic type of a cell value stored in an ODS document.
type CellType int
// Supported cell types. CellTypeEmpty represents an unset or cleared cell.
const (
CellTypeEmpty CellType = iota
CellTypeString
CellTypeFloat
CellTypeDate
CellTypeBool
CellTypeCurrency
CellTypePercentage
CellTypeTime
)
var cellTypeToODS = map[CellType]string{
CellTypeEmpty: "",
CellTypeString: "string",
CellTypeFloat: "float",
CellTypeDate: "date",
CellTypeBool: "boolean",
CellTypeCurrency: "currency",
CellTypePercentage: "percentage",
CellTypeTime: "time",
}
var odsToCellType = map[string]CellType{
"": CellTypeEmpty,
"string": CellTypeString,
"float": CellTypeFloat,
"date": CellTypeDate,
"boolean": CellTypeBool,
"currency": CellTypeCurrency,
"percentage": CellTypePercentage,
"time": CellTypeTime,
}
func (ct CellType) odsName() string {
return cellTypeToODS[ct]
}
func cellTypeFromODS(name string) CellType {
if ct, ok := odsToCellType[name]; ok {
return ct
}
return CellTypeString
}
func detectIntType(value interface{}) (CellType, string, bool) {
switch v := value.(type) {
case int:
return CellTypeFloat, strconv.FormatInt(int64(v), 10), true
case int8:
return CellTypeFloat, strconv.FormatInt(int64(v), 10), true
case int16:
return CellTypeFloat, strconv.FormatInt(int64(v), 10), true
case int32:
return CellTypeFloat, strconv.FormatInt(int64(v), 10), true
case int64:
return CellTypeFloat, strconv.FormatInt(v, 10), true
case uint:
return CellTypeFloat, strconv.FormatUint(uint64(v), 10), true
case uint8:
return CellTypeFloat, strconv.FormatUint(uint64(v), 10), true
case uint16:
return CellTypeFloat, strconv.FormatUint(uint64(v), 10), true
case uint32:
return CellTypeFloat, strconv.FormatUint(uint64(v), 10), true
case uint64:
return CellTypeFloat, strconv.FormatUint(v, 10), true
default:
return CellTypeEmpty, "", false
}
}
func detectCellType(value interface{}) (CellType, string) {
switch v := value.(type) {
case nil:
return CellTypeEmpty, ""
case string:
return CellTypeString, v
case float32:
return CellTypeFloat, strconv.FormatFloat(float64(v), 'f', -1, 32)
case float64:
return CellTypeFloat, strconv.FormatFloat(v, 'f', -1, 64)
case bool:
if v {
return CellTypeBool, "true"
}
return CellTypeBool, "false"
case time.Time:
return CellTypeDate, v.Format("2006-01-02T15:04:05")
case fmt.Stringer:
return CellTypeString, v.String()
default:
if ct, s, ok := detectIntType(value); ok {
return ct, s
}
return CellTypeString, fmt.Sprintf("%v", v)
}
}
func cellValueToString(valueType CellType, rawValue string) string {
switch valueType {
case CellTypeBool:
if rawValue == "true" {
return "TRUE"
}
return "FALSE"
default:
return rawValue
}
}
func parseFloat(raw string) (float64, error) {
return strconv.ParseFloat(raw, 64)
}
func parseInt(raw string) (int64, error) {
f, err := strconv.ParseFloat(raw, 64)
if err != nil {
return 0, err
}
return int64(f), nil
}
func parseBool(raw string) (bool, error) {
return strconv.ParseBool(raw)
}
func parseDate(raw string) (time.Time, error) {
formats := []string{
"2006-01-02T15:04:05",
"2006-01-02",
}
for _, f := range formats {
if t, err := time.Parse(f, raw); err == nil {
return t, nil
}
}
return time.Time{}, fmt.Errorf("goods: cannot parse date %q", raw)
}