mirror of
https://github.com/therootcompany/golib.git
synced 2025-10-07 01:28:19 +00:00
feat(colorsync): hard fork for maintenance
This commit is contained in:
parent
5eb3592744
commit
535bf2f824
22
colorjson/LICENSE
Normal file
22
colorjson/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Tyler Brock
|
||||
Copyright (c) 2025 AJ ONeal
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
65
colorjson/README.md
Normal file
65
colorjson/README.md
Normal file
@ -0,0 +1,65 @@
|
||||
# ColorJSON: The Fast Color JSON Marshaller for Go
|
||||
|
||||

|
||||
|
||||
## What is this?
|
||||
|
||||
This package is based heavily on hokaccha/go-prettyjson but has some noticeable differences:
|
||||
|
||||
- Over twice as fast (recursive descent serialization uses buffer instead of string concatenation)
|
||||
```
|
||||
BenchmarkColorJSONMarshall-4 500000 2498 ns/op
|
||||
BenchmarkPrettyJSON-4 200000 6145 ns/op
|
||||
```
|
||||
- more customizable (ability to have zero indent, print raw json strings, etc...)
|
||||
- better defaults (less bold colors)
|
||||
|
||||
ColorJSON was built in order to produce fast beautiful colorized JSON output for [Saw](http://github.com/TylerBrock/saw).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
go get -u github.com/therootcompany/golib/colorjson
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Setup
|
||||
|
||||
```go
|
||||
import "github.com/therootcompany/golib/colorjson"
|
||||
|
||||
str := `{
|
||||
"str": "foo",
|
||||
"num": 100,
|
||||
"bool": false,
|
||||
"null": null,
|
||||
"array": ["foo", "bar", "baz"],
|
||||
"obj": { "a": 1, "b": 2 }
|
||||
}`
|
||||
|
||||
// Create an intersting JSON object to marshal in a pretty format
|
||||
var obj map[string]interface{}
|
||||
json.Unmarshal([]byte(str), &obj)
|
||||
```
|
||||
|
||||
Vanilla Usage
|
||||
|
||||
```go
|
||||
s, _ := colorjson.Marshal(obj)
|
||||
fmt.Println(string(s))
|
||||
```
|
||||
|
||||
Customization (Custom Indent)
|
||||
|
||||
```go
|
||||
f := colorjson.NewFormatter()
|
||||
f.Indent = 2
|
||||
|
||||
s, _ := f.Marshal(v)
|
||||
fmt.Println(string(s))
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This is a fork of <https://github.com/TylerBrock/colorjson> for maintenance.
|
39
colorjson/benchmarks/colorjson_test.go
Normal file
39
colorjson/benchmarks/colorjson_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package colorjson_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/therootcompany/golib/colorjson"
|
||||
"github.com/hokaccha/go-prettyjson"
|
||||
)
|
||||
|
||||
func benchmarkMarshall(i int, b *testing.B) {
|
||||
simpleMap := make(map[string]interface{})
|
||||
simpleMap["a"] = 1
|
||||
simpleMap["b"] = "bee"
|
||||
simpleMap["c"] = [3]float64{1, 2, 3}
|
||||
simpleMap["d"] = [3]string{"one", "two", "three"}
|
||||
|
||||
// run the Fib function b.N times
|
||||
for n := 0; n < b.N; n++ {
|
||||
colorjson.Marshal(simpleMap)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkPrettyJSON(i int, b *testing.B) {
|
||||
simpleMap := make(map[string]interface{})
|
||||
simpleMap["a"] = 1
|
||||
simpleMap["b"] = "bee"
|
||||
simpleMap["c"] = [3]float64{1, 2, 3}
|
||||
simpleMap["d"] = [3]string{"one", "two", "three"}
|
||||
|
||||
// run the Fib function b.N times
|
||||
for n := 0; n < b.N; n++ {
|
||||
prettyjson.Marshal(simpleMap)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMarshall(b *testing.B) { benchmarkMarshall(100, b) }
|
||||
func BenchmarkMarshall1k(b *testing.B) { benchmarkMarshall(1000, b) }
|
||||
func BenchmarkPrettyJSON(b *testing.B) { benchmarkPrettyJSON(100, b) }
|
||||
func BenchmarkPrettyJSON1k(b *testing.B) { benchmarkPrettyJSON(1000, b) }
|
15
colorjson/benchmarks/go.mod
Normal file
15
colorjson/benchmarks/go.mod
Normal file
@ -0,0 +1,15 @@
|
||||
module github.com/therootcompany/golib/colorjson/benchmarks
|
||||
|
||||
go 1.18.0
|
||||
|
||||
require (
|
||||
github.com/therootcompany/golib/colorjson v0.0.0-20200706003622-8a50f05110d2
|
||||
github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
)
|
171
colorjson/colorjson.go
Normal file
171
colorjson/colorjson.go
Normal file
@ -0,0 +1,171 @@
|
||||
package colorjson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
const initialDepth = 0
|
||||
const valueSep = ","
|
||||
const null = "null"
|
||||
const startMap = "{"
|
||||
const endMap = "}"
|
||||
const startArray = "["
|
||||
const endArray = "]"
|
||||
|
||||
const emptyMap = startMap + endMap
|
||||
const emptyArray = startArray + endArray
|
||||
|
||||
type Formatter struct {
|
||||
KeyColor *color.Color
|
||||
StringColor *color.Color
|
||||
BoolColor *color.Color
|
||||
NumberColor *color.Color
|
||||
NullColor *color.Color
|
||||
StringMaxLength int
|
||||
Indent int
|
||||
DisabledColor bool
|
||||
RawStrings bool
|
||||
}
|
||||
|
||||
func NewFormatter() *Formatter {
|
||||
return &Formatter{
|
||||
KeyColor: color.New(color.FgWhite),
|
||||
StringColor: color.New(color.FgGreen),
|
||||
BoolColor: color.New(color.FgYellow),
|
||||
NumberColor: color.New(color.FgCyan),
|
||||
NullColor: color.New(color.FgMagenta),
|
||||
StringMaxLength: 0,
|
||||
DisabledColor: false,
|
||||
Indent: 0,
|
||||
RawStrings: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) sprintfColor(c *color.Color, format string, args ...interface{}) string {
|
||||
if f.DisabledColor || c == nil {
|
||||
return fmt.Sprintf(format, args...)
|
||||
}
|
||||
return c.SprintfFunc()(format, args...)
|
||||
}
|
||||
|
||||
func (f *Formatter) sprintColor(c *color.Color, s string) string {
|
||||
if f.DisabledColor || c == nil {
|
||||
return fmt.Sprint(s)
|
||||
}
|
||||
return c.SprintFunc()(s)
|
||||
}
|
||||
|
||||
func (f *Formatter) writeIndent(buf *bytes.Buffer, depth int) {
|
||||
buf.WriteString(strings.Repeat(" ", f.Indent*depth))
|
||||
}
|
||||
|
||||
func (f *Formatter) writeObjSep(buf *bytes.Buffer) {
|
||||
if f.Indent != 0 {
|
||||
buf.WriteByte('\n')
|
||||
} else {
|
||||
buf.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) Marshal(jsonObj interface{}) ([]byte, error) {
|
||||
buffer := bytes.Buffer{}
|
||||
f.marshalValue(jsonObj, &buffer, initialDepth)
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *Formatter) marshalMap(m map[string]interface{}, buf *bytes.Buffer, depth int) {
|
||||
remaining := len(m)
|
||||
|
||||
if remaining == 0 {
|
||||
buf.WriteString(emptyMap)
|
||||
return
|
||||
}
|
||||
|
||||
keys := make([]string, 0)
|
||||
for key := range m {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
buf.WriteString(startMap)
|
||||
f.writeObjSep(buf)
|
||||
|
||||
for _, key := range keys {
|
||||
f.writeIndent(buf, depth+1)
|
||||
buf.WriteString(f.KeyColor.Sprintf("\"%s\": ", key))
|
||||
f.marshalValue(m[key], buf, depth+1)
|
||||
remaining--
|
||||
if remaining != 0 {
|
||||
buf.WriteString(valueSep)
|
||||
}
|
||||
f.writeObjSep(buf)
|
||||
}
|
||||
f.writeIndent(buf, depth)
|
||||
buf.WriteString(endMap)
|
||||
}
|
||||
|
||||
func (f *Formatter) marshalArray(a []interface{}, buf *bytes.Buffer, depth int) {
|
||||
if len(a) == 0 {
|
||||
buf.WriteString(emptyArray)
|
||||
return
|
||||
}
|
||||
|
||||
buf.WriteString(startArray)
|
||||
f.writeObjSep(buf)
|
||||
|
||||
for i, v := range a {
|
||||
f.writeIndent(buf, depth+1)
|
||||
f.marshalValue(v, buf, depth+1)
|
||||
if i < len(a)-1 {
|
||||
buf.WriteString(valueSep)
|
||||
}
|
||||
f.writeObjSep(buf)
|
||||
}
|
||||
f.writeIndent(buf, depth)
|
||||
buf.WriteString(endArray)
|
||||
}
|
||||
|
||||
func (f *Formatter) marshalValue(val interface{}, buf *bytes.Buffer, depth int) {
|
||||
switch v := val.(type) {
|
||||
case map[string]interface{}:
|
||||
f.marshalMap(v, buf, depth)
|
||||
case []interface{}:
|
||||
f.marshalArray(v, buf, depth)
|
||||
case string:
|
||||
f.marshalString(v, buf)
|
||||
case float64:
|
||||
buf.WriteString(f.sprintColor(f.NumberColor, strconv.FormatFloat(v, 'f', -1, 64)))
|
||||
case bool:
|
||||
buf.WriteString(f.sprintColor(f.BoolColor, (strconv.FormatBool(v))))
|
||||
case nil:
|
||||
buf.WriteString(f.sprintColor(f.NullColor, null))
|
||||
case json.Number:
|
||||
buf.WriteString(f.sprintColor(f.NumberColor, v.String()))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) marshalString(str string, buf *bytes.Buffer) {
|
||||
if !f.RawStrings {
|
||||
strBytes, _ := json.Marshal(str)
|
||||
str = string(strBytes)
|
||||
}
|
||||
|
||||
if f.StringMaxLength != 0 && len(str) >= f.StringMaxLength {
|
||||
str = fmt.Sprintf("%s...", str[0:f.StringMaxLength])
|
||||
}
|
||||
|
||||
buf.WriteString(f.sprintColor(f.StringColor, str))
|
||||
}
|
||||
|
||||
// Marshal JSON data with default options
|
||||
func Marshal(jsonObj interface{}) ([]byte, error) {
|
||||
return NewFormatter().Marshal(jsonObj)
|
||||
}
|
30
colorjson/examples/indent/main.go
Normal file
30
colorjson/examples/indent/main.go
Normal file
@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/therootcompany/golib/colorjson"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := `{
|
||||
"str": "foo",
|
||||
"num": 100,
|
||||
"bool": false,
|
||||
"null": null,
|
||||
"array": ["foo", "bar", "baz"],
|
||||
"obj": { "a": 1, "b": 2 }
|
||||
}`
|
||||
|
||||
var obj map[string]interface{}
|
||||
json.Unmarshal([]byte(str), &obj)
|
||||
|
||||
// Make a custom formatter with indent set
|
||||
f := colorjson.NewFormatter()
|
||||
f.Indent = 4
|
||||
|
||||
// Marshall the Colorized JSON
|
||||
s, _ := f.Marshal(obj)
|
||||
fmt.Println(string(s))
|
||||
}
|
26
colorjson/examples/simple/main.go
Normal file
26
colorjson/examples/simple/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/therootcompany/golib/colorjson"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := `{
|
||||
"str": "foo",
|
||||
"num": 100,
|
||||
"bool": false,
|
||||
"null": null,
|
||||
"array": ["foo", "bar", "baz"],
|
||||
"obj": { "a": 1, "b": 2 }
|
||||
}`
|
||||
|
||||
var obj map[string]interface{}
|
||||
json.Unmarshal([]byte(str), &obj)
|
||||
|
||||
// Marshall the Colorized JSON
|
||||
s, _ := colorjson.Marshal(obj)
|
||||
fmt.Println(string(s))
|
||||
}
|
11
colorjson/go.mod
Normal file
11
colorjson/go.mod
Normal file
@ -0,0 +1,11 @@
|
||||
module github.com/therootcompany/golib/colorjson
|
||||
|
||||
go 1.18.0
|
||||
|
||||
require github.com/fatih/color v1.18.0
|
||||
|
||||
require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
)
|
11
colorjson/go.sum
Normal file
11
colorjson/go.sum
Normal file
@ -0,0 +1,11 @@
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
Loading…
x
Reference in New Issue
Block a user