|
|
|
|
@ -25,15 +25,22 @@ package ftext
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"ansi"
|
|
|
|
|
"bytes"
|
|
|
|
|
"bins/bfers"
|
|
|
|
|
"errs/collr"
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
|
|
|
|
|
|
TextBuilder struct {
|
|
|
|
|
f *TextFormatter
|
|
|
|
|
b bytes.Buffer
|
|
|
|
|
b *bfers.Buffer
|
|
|
|
|
|
|
|
|
|
useAux bool
|
|
|
|
|
auxB *bfers.Buffer
|
|
|
|
|
|
|
|
|
|
level int
|
|
|
|
|
ansiC ansi.Code
|
|
|
|
|
invalid error
|
|
|
|
|
}
|
|
|
|
|
@ -42,33 +49,238 @@ type (
|
|
|
|
|
TextBuilderFnc func (b *TextBuilder)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func newTextBuilder(formatter *TextFormatter) *TextBuilder {
|
|
|
|
|
return &TextBuilder{
|
|
|
|
|
f : formatter,
|
|
|
|
|
ansiC: formatter.layout.AnsiC}}
|
|
|
|
|
b := &TextBuilder {
|
|
|
|
|
f : formatter,
|
|
|
|
|
b : bfers.NewBuffer(),
|
|
|
|
|
useAux: len(formatter.valueTrans) > 0,
|
|
|
|
|
ansiC : formatter.layout.AnsiC,
|
|
|
|
|
}
|
|
|
|
|
if b.useAux {
|
|
|
|
|
b.auxB = bfers.NewBuffer()
|
|
|
|
|
} else {
|
|
|
|
|
b.auxB = b.b
|
|
|
|
|
}
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) Level () int {
|
|
|
|
|
return b.level }
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) AddText (text string) {
|
|
|
|
|
b.b.WriteString(text) }
|
|
|
|
|
|
|
|
|
|
func (s *TextBuilder) format (err error) {}
|
|
|
|
|
func (b *TextBuilder) AddTextAnsi (ansiC ansi.Code, text string) {
|
|
|
|
|
if b.f.ShowAnsi() {
|
|
|
|
|
if ansiC == 0 {
|
|
|
|
|
ansiC = b.ansiC
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteString(ansiC.Begin())
|
|
|
|
|
defer b.b.WriteString(ansiC.End())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
b.b.WriteString(text)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) SetAnsi(ansiC ansi.Code) {
|
|
|
|
|
if ansiC != 0 {
|
|
|
|
|
b.ansiC = ansiC
|
|
|
|
|
} else {
|
|
|
|
|
b.ansiC = b.f.layout.AnsiC
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) format (err error) {
|
|
|
|
|
|
|
|
|
|
c := collr.NewErrorCollection(err)
|
|
|
|
|
if c.Collect(b.f.AddFields(), b.f.AddCauses(), b.f.AddTrace()); c.Invalid != nil {
|
|
|
|
|
//b.writeFormatError(cl.Invalid)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
b.write(c,false, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) write (c *collr.ErrorCollection, cont bool, level int) {
|
|
|
|
|
if b.invalid != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ind := strings.Repeat(b.f.layout.Indent,level)
|
|
|
|
|
//ind2:= ind +b.f.layout.Indent
|
|
|
|
|
|
|
|
|
|
func (s *TextBuilder) setAnsi(ansiC ansi.Code) {
|
|
|
|
|
if ansiC != 0 {
|
|
|
|
|
s.ansiC = ansiC
|
|
|
|
|
} else {
|
|
|
|
|
s.ansiC = s.f.layout.AnsiC
|
|
|
|
|
d := false
|
|
|
|
|
f := b.f
|
|
|
|
|
b.level = level
|
|
|
|
|
if level == 0 {
|
|
|
|
|
b.f.sections.Main.begin(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer func(bl *TextBuilder, dn *bool,er error){
|
|
|
|
|
if !(*dn) {
|
|
|
|
|
if rc := recover(); rc != nil {
|
|
|
|
|
if er,is := rc.(error); is {
|
|
|
|
|
bl.invalid = er
|
|
|
|
|
} else {
|
|
|
|
|
bl.invalid = fmt.Errorf("%#v",rc)
|
|
|
|
|
}
|
|
|
|
|
bl.f.onFormatError(bl,er,bl.invalid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}(b,&d, c.Err)
|
|
|
|
|
|
|
|
|
|
f.sections.Head.begin(b)
|
|
|
|
|
b.writeFieldNameValue(collr.FieldNameError, c.ErrStr, ind)
|
|
|
|
|
if f.AddTypes() {
|
|
|
|
|
b.writeFieldNameValue(collr.FieldNameType,strings.Join(c.TypesStr,","), ind)
|
|
|
|
|
}
|
|
|
|
|
f.sections.Head.end(b)
|
|
|
|
|
|
|
|
|
|
if f.AddFields() && c.Fields.Len() > 0 {
|
|
|
|
|
f.sections.Fields.begin(b)
|
|
|
|
|
heads := c.Fields.GetHeads()
|
|
|
|
|
for _,fl := range heads {
|
|
|
|
|
b.writeField(c.Fields,fl,ind)
|
|
|
|
|
}
|
|
|
|
|
f.sections.Fields.end(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(c.Causes) > 0 {
|
|
|
|
|
if level == 0 {
|
|
|
|
|
f.sections.Causes.begin(b)
|
|
|
|
|
} else {
|
|
|
|
|
panic("Error ocurrido")
|
|
|
|
|
}
|
|
|
|
|
b.level++
|
|
|
|
|
for _,cs := range c.Causes {
|
|
|
|
|
f.sections.Cause.begin(b)
|
|
|
|
|
b.write(&cs,false,level+1)
|
|
|
|
|
f.sections.Cause.end(b)
|
|
|
|
|
}
|
|
|
|
|
if level == 0 {
|
|
|
|
|
f.sections.Causes.end(b)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.Trace != nil {
|
|
|
|
|
f.sections.Trace.begin(b)
|
|
|
|
|
for nu,fm := range c.Trace.Frames() {
|
|
|
|
|
b.f.frameBuilder(b,fm,nu)
|
|
|
|
|
}
|
|
|
|
|
f.sections.Trace.end(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if level == 0 {
|
|
|
|
|
b.f.sections.Main.end(b)
|
|
|
|
|
}
|
|
|
|
|
d = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (s *TextBuilder) reset () {
|
|
|
|
|
s.b.Reset()
|
|
|
|
|
s.f = nil
|
|
|
|
|
s.invalid = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) reset () {
|
|
|
|
|
b.b.Reset()
|
|
|
|
|
if b.useAux {
|
|
|
|
|
b.auxB.Reset()
|
|
|
|
|
b.useAux = false
|
|
|
|
|
}
|
|
|
|
|
b.f = nil
|
|
|
|
|
b.level = 0
|
|
|
|
|
b.invalid = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) writeFieldBegin (name, indent string) {
|
|
|
|
|
if b.ansiC != 0 {
|
|
|
|
|
b.b.WriteString(b.ansiC.Begin())
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteString(indent)
|
|
|
|
|
b.b.WriteString(b.f.nameTrans.Transform(name))
|
|
|
|
|
b.b.WriteString(b.f.layout.FieldSep)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) writeFieldEnd () {
|
|
|
|
|
b.b.WriteByte('\n')
|
|
|
|
|
if b.ansiC != 0 {
|
|
|
|
|
b.b.WriteString(b.ansiC.End())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) writeFieldNameValue(name string, value string, indent string) {
|
|
|
|
|
p:= b.b.Len()
|
|
|
|
|
b.writeFieldBegin(name,indent)
|
|
|
|
|
if b.f.IgnoreEmpty() && len(value) == 0 {
|
|
|
|
|
b.b.Truncate(p)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
b.b.WriteString(b.f.valueTrans.Transform(value))
|
|
|
|
|
b.writeFieldEnd()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) writeField (fields collr.Fields, field *collr.FieldHead, indent string) {
|
|
|
|
|
p := b.b.Len()
|
|
|
|
|
b.writeFieldBegin(field.Name,indent)
|
|
|
|
|
if !b.writeFieldValue(fields,field) {
|
|
|
|
|
b.b.Truncate(p)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
b.writeFieldEnd()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *TextBuilder) writeFieldValue (fields collr.Fields, field *collr.FieldHead) bool {
|
|
|
|
|
|
|
|
|
|
switch field.Kind {
|
|
|
|
|
case collr.FieldKindFloat:
|
|
|
|
|
b.auxB.WriteFloatStr(fields.GetFieldValueFloat(field),'f',-1)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindInt:
|
|
|
|
|
b.auxB.WriteIntStr(int64(fields.GetFieldValueInt(field)),10)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindString:
|
|
|
|
|
s := fields.GetFieldValueString(field)
|
|
|
|
|
if b.f.IgnoreEmpty() && len(s) == 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
b.auxB.WriteString(fields.GetFieldValueString(field))
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindTime:
|
|
|
|
|
b.auxB.WriteDateStr(fields.GetFieldValueDate(field), b.f.layout.TimeLayout)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindDate:
|
|
|
|
|
b.auxB.WriteDateStr(fields.GetFieldValueDate(field), b.f.layout.DateLayout)
|
|
|
|
|
|
|
|
|
|
case collr.FieldKindBool:
|
|
|
|
|
b.auxB.WriteBoolStr(fields.GetFieldValueBool(field))
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
a := fields.GetFieldValueAny(field)
|
|
|
|
|
if a == nil {
|
|
|
|
|
if b.f.IgnoreEmpty() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
b.auxB.WOQ(false,'"',g.nullValue)
|
|
|
|
|
} else {
|
|
|
|
|
s := fmt.Sprintf("%#v",a)
|
|
|
|
|
if b.f.IgnoreEmpty() && len(s) == 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
b.auxB.WriteString(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if b.useAux {
|
|
|
|
|
b.b.WriteString(b.f.valueTrans.Transform(string(b.auxB.Bytes())))
|
|
|
|
|
b.auxB.Reset()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|