|
|
|
|
@ -25,8 +25,8 @@ package fjson
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bins/bfers"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"errs/fmtr/collr"
|
|
|
|
|
"fmt"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
@ -64,15 +64,15 @@ func newJsonBuilder (f *JSONFormatter) *jsonBuilder {
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) format (err error) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
b.write(*collr.NewErrorCollection(err).Collect(true,true,true),"",false)
|
|
|
|
|
cl := collr.NewErrorCollection(err)
|
|
|
|
|
cl.Collect(b.f.AddFields(),b.f.AddCauses(),b.f.AddTrace())
|
|
|
|
|
b.write(cl,"",false)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) write (coll collr.ErrorCollection,indent string, cont bool) {
|
|
|
|
|
var in string
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont bool) {
|
|
|
|
|
in := ""
|
|
|
|
|
if b.pretty {
|
|
|
|
|
in = indent + strings.Repeat(b.indent, 1)
|
|
|
|
|
if !cont {
|
|
|
|
|
@ -80,20 +80,25 @@ func (b *jsonBuilder) write (coll collr.ErrorCollection,indent string, cont bool
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
b.b.WriteByte('{')
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
b.writeField("error",coll.ErrStr,in,true,true)
|
|
|
|
|
b.writeField("error",coll.ErrStr,in,true,false, false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if b.f.AddTypes() {
|
|
|
|
|
types := coll.Types
|
|
|
|
|
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(types) == 1 {
|
|
|
|
|
b.writeField("type",types[0].String(),in,true,false)
|
|
|
|
|
b.writeField("type", types[0].String(), in, true, false,false)
|
|
|
|
|
} else {
|
|
|
|
|
b.writeObject("types", in, '[', b.pretty)
|
|
|
|
|
b.writeOpen("types", in, '[', b.pretty)
|
|
|
|
|
for i, t := range coll.Types {
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(in)
|
|
|
|
|
@ -109,86 +114,95 @@ func (b *jsonBuilder) write (coll collr.ErrorCollection,indent string, cont bool
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(in)
|
|
|
|
|
b.b.Write2Byte(']', ',')
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
} else {
|
|
|
|
|
b.b.Write2Byte(']', ',')
|
|
|
|
|
|
|
|
|
|
b.writeClose(in, ']')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
heads := coll.Fields.GetHeads()
|
|
|
|
|
if len(heads) > 0 {
|
|
|
|
|
b.writeObject("fields", in, '{', b.pretty)
|
|
|
|
|
for i, h := range coll.Fields.GetHeads() {
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(in)
|
|
|
|
|
b.b.WriteString(b.indent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(h.Name)
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(b.sep)
|
|
|
|
|
b.writeFieldValue(coll.Fields, h)
|
|
|
|
|
if i < len(heads)-1 {
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
}
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coll.Fields.Sort()
|
|
|
|
|
b.writeOpen("fields", in, '{', b.pretty)
|
|
|
|
|
var n = 0
|
|
|
|
|
var fi string
|
|
|
|
|
if b.pretty {
|
|
|
|
|
fi = in + b.indent
|
|
|
|
|
}
|
|
|
|
|
for _, h := range heads {
|
|
|
|
|
p := b.b.Len()
|
|
|
|
|
|
|
|
|
|
if n > 0 {
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(in)
|
|
|
|
|
b.b.Write2Byte('}', ',')
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
} else {
|
|
|
|
|
b.b.Write2Byte('}', ',')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.writeFieldName(h.Name,fi)
|
|
|
|
|
|
|
|
|
|
if !b.writeFieldValue(coll.Fields, h) {
|
|
|
|
|
b.b.Truncate(p)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
n++
|
|
|
|
|
}
|
|
|
|
|
if n > 0 && b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
b.writeClose(in,'}')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
causes := coll.Causes
|
|
|
|
|
if len (causes) > 0 {
|
|
|
|
|
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(causes) == 1 {
|
|
|
|
|
b.writeObject("cause",in,0,false)
|
|
|
|
|
b.write(causes[0],strings.Repeat(b.indent,1),true)
|
|
|
|
|
b.writeOpen("cause", in, 0, false)
|
|
|
|
|
b.write(&causes[0], strings.Repeat(b.indent, 1), true)
|
|
|
|
|
} else if len(causes) > 1 {
|
|
|
|
|
b.writeObject("causes", in, '[', b.pretty)
|
|
|
|
|
b.writeOpen("causes", in, '[', b.pretty)
|
|
|
|
|
var ci string
|
|
|
|
|
if b.pretty {
|
|
|
|
|
ci = strings.Repeat(b.indent, 2)
|
|
|
|
|
}
|
|
|
|
|
for _,ce := range causes {
|
|
|
|
|
b.write(ce,ci,false)
|
|
|
|
|
for i, ce := range causes {
|
|
|
|
|
if i > 0 {
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteString(in)
|
|
|
|
|
b.b.WriteByte(']')
|
|
|
|
|
}
|
|
|
|
|
b.write(&ce, ci, false)
|
|
|
|
|
}
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.writeEndObject(indent,'}')
|
|
|
|
|
b.writeClose(in, ']')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(indent)
|
|
|
|
|
b.b.WriteByte('}')
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
} else {
|
|
|
|
|
b.b.WriteByte('}')
|
|
|
|
|
}
|
|
|
|
|
b.writeClose(indent,'}')
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeObject(name, indent string, object byte,nl bool) {
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(indent)
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(name)
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(b.sep)
|
|
|
|
|
func (b *jsonBuilder) writeOpen(name, indent string, object byte,nl bool) {
|
|
|
|
|
b.writeFieldName(name,indent)
|
|
|
|
|
if object != 0 {
|
|
|
|
|
b.b.WriteByte(object)
|
|
|
|
|
}
|
|
|
|
|
@ -197,23 +211,29 @@ func (b *jsonBuilder) writeObject(name, indent string, object byte,nl bool) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeEndObject (indent string, object byte) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeClose(indent string, object byte) {
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(indent)
|
|
|
|
|
b.b.WriteByte(object)
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
} else {
|
|
|
|
|
b.b.WriteByte(object)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeField (name, value, indent string, quote, coma bool) {
|
|
|
|
|
func (b *jsonBuilder) writeFieldName (name, indent string) {
|
|
|
|
|
if b.pretty {
|
|
|
|
|
b.b.WriteString(indent)
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(name)
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
b.b.WriteString(b.sep)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeField (name, value, indent string, quote, coma, nl bool) {
|
|
|
|
|
b.writeFieldName(name,indent)
|
|
|
|
|
if quote {
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
}
|
|
|
|
|
@ -224,34 +244,93 @@ func (b *jsonBuilder) writeField (name, value, indent string, quote, coma bool)
|
|
|
|
|
if coma {
|
|
|
|
|
b.b.WriteByte(',')
|
|
|
|
|
}
|
|
|
|
|
if b.pretty {
|
|
|
|
|
if b.pretty && nl {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *jsonBuilder) writeFieldValue (fields collr.Fields, field *collr.FieldHead) {
|
|
|
|
|
func (b *jsonBuilder) writeFieldValue (fields collr.Fields, field *collr.FieldHead) bool {
|
|
|
|
|
var v []byte
|
|
|
|
|
q := true
|
|
|
|
|
|
|
|
|
|
switch field.Kind {
|
|
|
|
|
case collr.FieldKindFloat : v = strconv.AppendFloat(v,fields.GetFieldValueFloat(field),'E',-1,64)
|
|
|
|
|
case collr.FieldKindFloat :
|
|
|
|
|
n := fields.GetFieldValueFloat(field)
|
|
|
|
|
if n == 0 {
|
|
|
|
|
if b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = g.zero
|
|
|
|
|
} else {
|
|
|
|
|
v = strconv.AppendFloat(v, n, 'E', -1, 64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindInt :
|
|
|
|
|
v = strconv.AppendInt(v,int64(fields.GetFieldValueInt(field)),10)
|
|
|
|
|
q = false
|
|
|
|
|
case collr.FieldKindString: v = []byte(fields.GetFieldValueString(field))
|
|
|
|
|
case collr.FieldKindTime : v = fields.GetFieldValueDate(field).AppendFormat(v,time.RFC822Z)
|
|
|
|
|
case collr.FieldKindDate : v = fields.GetFieldValueDate(field).AppendFormat(v,time.RFC822Z)
|
|
|
|
|
n := fields.GetFieldValueInt(field)
|
|
|
|
|
if n == 0 {
|
|
|
|
|
if b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = g.zero
|
|
|
|
|
} else {
|
|
|
|
|
v = strconv.AppendInt(v, int64(n), 10)
|
|
|
|
|
}
|
|
|
|
|
q = b.f.UseQuote()
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindString:
|
|
|
|
|
s := fields.GetFieldValueString(field)
|
|
|
|
|
if len(s) == 0 && b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = []byte(s)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindTime :
|
|
|
|
|
d := fields.GetFieldValueDate(field)
|
|
|
|
|
if d.IsZero() && b.f.IgnoreDefaults(){
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = d.AppendFormat(v,time.RFC822Z)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindDate :
|
|
|
|
|
d := fields.GetFieldValueDate(field)
|
|
|
|
|
if d.IsZero() && b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = d.AppendFormat(v,time.RFC822Z)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindBool :
|
|
|
|
|
v = strconv.AppendBool(v,fields.GetFieldValueBool(field))
|
|
|
|
|
q = false
|
|
|
|
|
t := fields.GetFieldValueBool(field)
|
|
|
|
|
if !t {
|
|
|
|
|
if b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = g.vfalse
|
|
|
|
|
} else {
|
|
|
|
|
v = g.vtrue
|
|
|
|
|
}
|
|
|
|
|
q = b.f.UseQuote()
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
v = []byte(fmt.Sprintf("%v",fields.GetFieldValueAny(field)))
|
|
|
|
|
a := fields.GetFieldValueAny(field)
|
|
|
|
|
if a == nil {
|
|
|
|
|
if b.f.IgnoreDefaults() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
v = g.null
|
|
|
|
|
} else {
|
|
|
|
|
var e error
|
|
|
|
|
if v,e = json.Marshal(a); e != nil {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if q {
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
}
|
|
|
|
|
b.b.Write(v)
|
|
|
|
|
_,_ = b.b.Write(v)
|
|
|
|
|
if q {
|
|
|
|
|
b.b.WriteByte('"')
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|