diff --git a/app/main.go b/app/main.go index 5fb2fe5..7559529 100644 --- a/app/main.go +++ b/app/main.go @@ -94,13 +94,19 @@ func main() { errs.ErrInfoWithInfo("Mi mensaje")) + mu := errs.NewErrMulti( + errs.ErrCode("UnError"), + errs.ErrCode("UnOtro"), + me, + ) + //printCollection(*collr.NewErrorCollection(me).Collect(true,true,true)) jso := fjson.NewJSONFormatter() - fmt.Print(string(jso.FormatError(me))) + fmt.Print(string(jso.FormatError(mu))) } diff --git a/core/errs/fmtr/fjson/active.go b/core/errs/fmtr/fjson/active.go index a4ac845..6e2d0fb 100644 --- a/core/errs/fmtr/fjson/active.go +++ b/core/errs/fmtr/fjson/active.go @@ -24,6 +24,8 @@ package fjson + + var ( G = struct { @@ -31,8 +33,16 @@ var ( }{} g = struct { - - }{} + null []byte + zero []byte + vfalse []byte + vtrue []byte + }{ + null : []byte("null"), + zero : []byte{'0'}, + vfalse: []byte{'f','a','l','s','e'}, + vtrue: []byte{'t','r','u','e'}, + } ) diff --git a/core/errs/fmtr/fjson/json_builder.go b/core/errs/fmtr/fjson/json_builder.go index 210256f..0f779ab 100644 --- a/core/errs/fmtr/fjson/json_builder.go +++ b/core/errs/fmtr/fjson/json_builder.go @@ -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,115 +80,129 @@ 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) - types := coll.Types - if len(types) == 1 { - b.writeField("type",types[0].String(),in,true,false) - } else { - b.writeObject("types", in, '[', b.pretty) - for i, t := range coll.Types { - if b.pretty { - b.b.WriteString(in) - b.b.WriteString(b.indent) - } - b.b.WriteByte('"') - b.b.WriteString(t.String()) - b.b.WriteByte('"') - if i < len(coll.Types)-1 { - b.b.WriteByte(',') - } - if b.pretty { - b.b.WriteByte('\n') - } - } + if b.f.AddTypes() { + types := coll.Types + + b.b.WriteByte(',') if b.pretty { - b.b.WriteString(in) - b.b.Write2Byte(']', ',') b.b.WriteByte('\n') + } + + if len(types) == 1 { + b.writeField("type", types[0].String(), in, true, false,false) } else { - b.b.Write2Byte(']', ',') + b.writeOpen("types", in, '[', b.pretty) + for i, t := range coll.Types { + if b.pretty { + b.b.WriteString(in) + b.b.WriteString(b.indent) + } + b.b.WriteByte('"') + b.b.WriteString(t.String()) + b.b.WriteByte('"') + if i < len(coll.Types)-1 { + b.b.WriteByte(',') + } + if b.pretty { + b.b.WriteByte('\n') + } + } + + 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.WriteByte('\n') + } } - if b.pretty { - b.b.WriteByte('\n') + + b.writeFieldName(h.Name,fi) + + if !b.writeFieldValue(coll.Fields, h) { + b.b.Truncate(p) + continue } + n++ } - if b.pretty { - b.b.WriteString(in) - b.b.Write2Byte('}', ',') + if n > 0 && b.pretty { b.b.WriteByte('\n') - } else { - b.b.Write2Byte('}', ',') } - + b.writeClose(in,'}') } causes := coll.Causes - if len(causes) == 1 { - b.writeObject("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) - var ci string + if len (causes) > 0 { + + b.b.WriteByte(',') if b.pretty { - ci = strings.Repeat(b.indent,2) + b.b.WriteByte('\n') } - for _,ce := range causes { - b.write(ce,ci,false) + + if len(causes) == 1 { + b.writeOpen("cause", in, 0, false) + b.write(&causes[0], strings.Repeat(b.indent, 1), true) + } else if len(causes) > 1 { + b.writeOpen("causes", in, '[', b.pretty) + var ci string + if b.pretty { + ci = strings.Repeat(b.indent, 2) + } + for i, ce := range causes { + if i > 0 { + b.b.WriteByte(',') + if b.pretty { + b.b.WriteByte('\n') + } + } + b.write(&ce, ci, false) + } + if b.pretty { + b.b.WriteByte('\n') + } + b.writeClose(in, ']') } - b.b.WriteString(in) - b.b.WriteByte(']') - b.b.WriteByte('\n') } - b.writeEndObject(indent,'}') - 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) { - b.b.WriteString(indent) +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 } diff --git a/core/errs/fmtr/fjson/json_formatter.go b/core/errs/fmtr/fjson/json_formatter.go index edc344c..59001ca 100644 --- a/core/errs/fmtr/fjson/json_formatter.go +++ b/core/errs/fmtr/fjson/json_formatter.go @@ -38,7 +38,7 @@ type ( func NewJSONFormatter (options ...JSONFormatterFnc) *JSONFormatter { f := &JSONFormatter{ - Option: ShowPretty |UseSpace, + Option: ShowPretty |UseSpace | AddTypes |AddFields | AddCauses | AddTrace | IgnoreDefaults, indent: " ", } for _,o := range options { diff --git a/core/errs/fmtr/fjson/option.go b/core/errs/fmtr/fjson/option.go index c66f0d8..f4395af 100644 --- a/core/errs/fmtr/fjson/option.go +++ b/core/errs/fmtr/fjson/option.go @@ -28,20 +28,47 @@ package fjson const ( - ShowPretty Option = 1 + iota + AddTypes Option = 1 << iota + AddFields + AddCauses + AddTrace + ShowPretty UseSpace - UseNumQuoted + UseQuote + IgnoreDefaults + SortFields ) type ( - Option uint8 + Option uint16 ) +func (o Option) AddTypes () bool { + return o&AddTypes != 0 } + +func (o Option) AddFields () bool { + return o&AddFields != 0 } + +func (o Option) AddCauses () bool { + return o&AddCauses != 0 } + +func (o Option) AddTrace () bool { + return o&AddTrace != 0 } func (o Option) ShowPretty () bool { return o&ShowPretty != 0 } func (o Option) UseSpace () bool { - return o&UseSpace != 0 } \ No newline at end of file + return o&UseSpace != 0 } + +func (o Option) UseQuote () bool { + return o&UseQuote != 0 } + +func (o Option) SortFields () bool { + return o&SortFields != 0 } + +func (o Option) IgnoreDefaults() bool { + return o&IgnoreDefaults != 0 } +