/
output.go
103 lines (88 loc) · 2.42 KB
/
output.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
package process
import (
"bytes"
"fmt"
"io"
"sync"
"github.com/charmbracelet/lipgloss"
)
// https://observablehq.com/@d3/color-schemes#Category10
var colors = []lipgloss.Style{
lipgloss.NewStyle().Foreground(lipgloss.Color("#1f77b4")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#ff7f0e")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#2ca02c")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#d62728")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#9467bd")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#8c564b")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#e377c2")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#7f7f7f")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#bcbd22")),
lipgloss.NewStyle().Foreground(lipgloss.Color("#17becf")),
}
type MuxWriter interface {
Writer(string) io.Writer
RegisterName(string) (int, lipgloss.Style)
}
type muxWriterFactory struct {
lck sync.Mutex
dst io.Writer
pfxlen int
clr map[string]lipgloss.Style
}
func NewMuxWriter(dst io.Writer) MuxWriter {
return &muxWriterFactory{
dst: dst,
clr: make(map[string]lipgloss.Style),
}
}
func (mwf *muxWriterFactory) RegisterName(name string) (int, lipgloss.Style) {
if len(name) > mwf.pfxlen {
mwf.pfxlen = len(name)
}
if _, ok := mwf.clr[name]; !ok {
mwf.clr[name] = colors[len(mwf.clr)%len(colors)]
}
return mwf.pfxlen, mwf.clr[name]
}
func (mwf *muxWriterFactory) prefix(name string) []byte {
pfxlen, style := mwf.RegisterName(name)
templ := fmt.Sprintf("%%-%ds | ", pfxlen)
return []byte(style.Render(fmt.Sprintf(templ, name)))
}
func (mwf *muxWriterFactory) Writer(name string) io.Writer {
mwf.lck.Lock()
defer mwf.lck.Unlock()
mwf.RegisterName(name)
return &muxWriter{
muxWriterFactory: mwf,
buf: new(bytes.Buffer),
name: name,
}
}
type muxWriter struct {
*muxWriterFactory
buf *bytes.Buffer
name string
}
func (mw *muxWriter) Write(p []byte) (int, error) {
mw.lck.Lock()
defer mw.lck.Unlock()
rdr := bytes.NewBuffer(p)
pre := mw.prefix(mw.name)
count := 0
var line []byte
var err error
for line, err = rdr.ReadBytes('\n'); err == nil; line, err = rdr.ReadBytes('\n') {
if _, err := mw.dst.Write(append(pre, line...)); err != nil {
return count, err
}
count += len(line)
}
if len(line) > 0 {
if _, err := mw.dst.Write(append(pre, append(line, '\n')...)); err != nil {
return count, err
}
count += len(line)
}
return count, nil
}