2020-08-06 20:58:47 +03:00
|
|
|
package internal
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
fcolor "github.com/fatih/color"
|
|
|
|
|
|
|
|
"github.com/neilotoole/sq/cli/output"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Colors encapsulates colorization of JSON output.
|
|
|
|
type Colors struct {
|
|
|
|
Null Color
|
|
|
|
Bool Color
|
|
|
|
Number Color
|
|
|
|
String Color
|
|
|
|
Key Color
|
|
|
|
Bytes Color
|
|
|
|
Time Color
|
|
|
|
Punc Color
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendNull appends a colorized "null" to b.
|
|
|
|
func (c Colors) AppendNull(b []byte) []byte {
|
|
|
|
b = append(b, c.Null.Prefix...)
|
|
|
|
b = append(b, "null"...)
|
|
|
|
return append(b, c.Null.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendBool appends the colorized bool v to b.
|
|
|
|
func (c Colors) AppendBool(b []byte, v bool) []byte {
|
|
|
|
b = append(b, c.Bool.Prefix...)
|
|
|
|
|
|
|
|
if v {
|
|
|
|
b = append(b, "true"...)
|
|
|
|
} else {
|
|
|
|
b = append(b, "false"...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return append(b, c.Bool.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendKey appends the colorized key v to b.
|
2022-12-18 11:35:59 +03:00
|
|
|
func (c Colors) AppendKey(b, v []byte) []byte {
|
2020-08-06 20:58:47 +03:00
|
|
|
b = append(b, c.Key.Prefix...)
|
|
|
|
b = append(b, v...)
|
|
|
|
return append(b, c.Key.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendInt64 appends the colorized int64 v to b.
|
|
|
|
func (c Colors) AppendInt64(b []byte, v int64) []byte {
|
|
|
|
b = append(b, c.Number.Prefix...)
|
|
|
|
b = strconv.AppendInt(b, v, 10)
|
|
|
|
return append(b, c.Number.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendUint64 appends the colorized uint64 v to b.
|
|
|
|
func (c Colors) AppendUint64(b []byte, v uint64) []byte {
|
|
|
|
b = append(b, c.Number.Prefix...)
|
|
|
|
b = strconv.AppendUint(b, v, 10)
|
|
|
|
return append(b, c.Number.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppendPunc appends the colorized punctuation mark v to b.
|
|
|
|
func (c Colors) AppendPunc(b []byte, v byte) []byte {
|
|
|
|
b = append(b, c.Punc.Prefix...)
|
|
|
|
b = append(b, v)
|
|
|
|
return append(b, c.Punc.Suffix...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Color is used to render terminal colors. The Prefix
|
|
|
|
// value is written, then the actual value, then the suffix.
|
|
|
|
type Color struct {
|
|
|
|
// Prefix is the terminal color code prefix to print before the value (may be empty).
|
|
|
|
Prefix []byte
|
|
|
|
|
|
|
|
// Suffix is the terminal color code suffix to print after the value (may be empty).
|
|
|
|
Suffix []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// newColor creates a Color instance from a fatih/color instance.
|
|
|
|
func newColor(c *fcolor.Color) Color {
|
|
|
|
// Dirty conversion function ahead: print
|
|
|
|
// a space using c, then grab the bytes printed
|
|
|
|
// before and after the space, and those are the
|
|
|
|
// bytes we need for the prefix and suffix.
|
|
|
|
|
|
|
|
if c == nil {
|
|
|
|
return Color{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make a copy because the pkg-level color.NoColor could be false.
|
|
|
|
c2 := *c
|
|
|
|
c2.EnableColor()
|
|
|
|
|
|
|
|
b := []byte(c2.Sprint(" "))
|
|
|
|
i := bytes.IndexByte(b, ' ')
|
|
|
|
if i <= 0 {
|
|
|
|
return Color{}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Color{Prefix: b[:i], Suffix: b[i+1:]}
|
|
|
|
}
|
|
|
|
|
2023-04-22 06:36:32 +03:00
|
|
|
// NewColors builds a Colors instance from a Printing instance.
|
|
|
|
func NewColors(pr *output.Printing) Colors {
|
|
|
|
if pr == nil || pr.IsMonochrome() {
|
2020-08-06 20:58:47 +03:00
|
|
|
return Colors{}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Colors{
|
2023-04-22 06:36:32 +03:00
|
|
|
Null: newColor(pr.Null),
|
|
|
|
Bool: newColor(pr.Bool),
|
|
|
|
Bytes: newColor(pr.Bytes),
|
|
|
|
Number: newColor(pr.Number),
|
|
|
|
String: newColor(pr.String),
|
|
|
|
Time: newColor(pr.Datetime),
|
|
|
|
Key: newColor(pr.Key),
|
|
|
|
Punc: newColor(pr.Punc),
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
}
|