-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwriter.go
86 lines (73 loc) · 1.8 KB
/
writer.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
package main
import (
"bytes"
"encoding/csv"
"fmt"
"io"
"sync"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
var (
bpool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
json = jsoniter.ConfigFastest
ErrIsNotObjectForCsv = errors.New("unexpected type for csv")
)
func writeJson(val interface{}) (*bytes.Buffer, error) {
buf, ok := bpool.Get().(*bytes.Buffer)
if !ok {
return nil, errors.Errorf("failed type assertion to *bytes.Buffer")
}
err := json.NewEncoder(buf).Encode(val)
if err != nil {
buf.Reset()
bpool.Put(buf)
return nil, errors.WithMessage(err, "encode json value")
}
return buf, nil
}
func writeCsv(val interface{}, entity Entity) (*bytes.Buffer, error) {
buf, ok := bpool.Get().(*bytes.Buffer)
if !ok {
return nil, errors.Errorf("failed type assertion to *bytes.Buffer")
}
switch m := val.(type) {
case map[string]interface{}:
csvWriter := csv.NewWriter(buf)
if entity.Config.CsvSeparator != "" {
csvWriter.Comma = []rune(entity.Config.CsvSeparator)[0]
}
columns := make([]string, 0, len(m))
for _, column := range entity.CsvColumns() {
if v, ok := m[column]; ok {
columns = append(columns, fmt.Sprintf("%v", v))
} else {
columns = append(columns, "")
}
}
err := csvWriter.Write(columns)
if err != nil {
buf.Reset()
bpool.Put(buf)
return nil, errors.WithMessage(err, "write csv columns")
}
csvWriter.Flush()
default:
return nil, ErrIsNotObjectForCsv
}
return buf, nil
}
func newWriterWorker(bytesCh <-chan *bytes.Buffer, wg *sync.WaitGroup, writer io.Writer) {
defer wg.Done()
for buf := range bytesCh {
_, err := buf.WriteTo(writer)
if err != nil {
fmt.Println(errors.WithMessage(err, "unexpected write error")) // nolint:forbidigo
}
bpool.Put(buf)
}
}