corregido el formateador de error para que no escriba la seccion Causes en caso de que no tenga ninguna

master
DEV 2 years ago
parent 4b14eff493
commit 38177ccf76

@ -3,8 +3,8 @@ package main
import (
"bins/bfers"
"errs"
"errs/fmtr/collr"
"errs/fmtr/fjson"
"errs/collr"
"errs/collr/fjson"
"errs/stack"
"fmt"
)
@ -64,6 +64,16 @@ func (c MiCustomErr) Unwrap () error {
return c.error
}
func (c MiCustomErr) Collect (collector collr.Collector) {
collector.AddFieldAny("UnoCualquiera",struct {
A string
B int
}{
A : "UUnA",
B : 3,
})
}
func printCollection (ec collr.ErrorCollection) {
if ec.Invalid != nil {
@ -106,7 +116,7 @@ func main() {
jso := fjson.NewJSONFormatter()
fmt.Print(string(jso.FormatError(mu)))
fmt.Print(string(jso.FormatError(errs.WrapWithTrace(mu,1))))
}

@ -40,19 +40,19 @@ const (
var (
G = struct {
ErrOutOfRange Err
ErrWriteCount Err
ErrTooShort Err
ErrTooLarge Err
ErrNegativeRead Err
ErrUnreadInvalid Err
ErrOutOfRange ErrBuffer
ErrWriteCount ErrBuffer
ErrTooShort ErrBuffer
ErrTooLarge ErrBuffer
ErrNegativeRead ErrBuffer
ErrUnreadInvalid ErrBuffer
}{
ErrOutOfRange: Err{errs.ErrCode("out-of-range")},
ErrWriteCount: Err{errs.ErrCode("write-count")},
ErrTooShort: Err{errs.ErrCode("too-short")},
ErrTooLarge: Err{errs.ErrCode("too-large")},
ErrNegativeRead: Err{errs.ErrCode("negative-read")},
ErrUnreadInvalid: Err{errs.ErrCode("unread-invalid")},
ErrOutOfRange: ErrBuffer{errs.ErrCode("out-of-range")},
ErrWriteCount: ErrBuffer{errs.ErrCode("write-count")},
ErrTooShort: ErrBuffer{errs.ErrCode("too-short")},
ErrTooLarge: ErrBuffer{errs.ErrCode("too-large")},
ErrNegativeRead: ErrBuffer{errs.ErrCode("negative-read")},
ErrUnreadInvalid: ErrBuffer{errs.ErrCode("unread-invalid")},
}
g = struct {

@ -29,6 +29,6 @@ import (
type (
Err struct { errs.ErrCode }
ErrBuffer struct { errs.ErrCode }
)

@ -28,13 +28,11 @@ import (
"unicode/utf8"
)
func (b *Buffer) WriteBoolStr(value bool) {
b.lastOp = opInvalid
b.data = strconv.AppendBool(b.data, value)
}
func (b *Buffer) WriteRuneStr(value rune) int {
if value < utf8.RuneSelf {
b.WriteByte(byte(value))
@ -47,7 +45,6 @@ func (b *Buffer) WriteRuneStr(value rune) int {
return cn
}
func (b *Buffer) WriteUIntStr(value uint64, base int) {
b.lastOp = opInvalid
if base == 0 {
@ -56,7 +53,6 @@ func (b *Buffer) WriteUIntStr(value uint64, base int) {
b.data = strconv.AppendUint(b.data, value, base)
}
func (b *Buffer) WriteIntStr(value int64, base int) {
b.lastOp = opInvalid
if base == 0 {
@ -65,7 +61,6 @@ func (b *Buffer) WriteIntStr(value int64, base int) {
b.data = strconv.AppendInt(b.data, value, base)
}
func (b *Buffer) WriteFloatStr(value float64, formatter byte, precision int) {
b.lastOp = opInvalid
if formatter == 0 {
@ -74,7 +69,6 @@ func (b *Buffer) WriteFloatStr(value float64, formatter byte, precision int) {
b.data = strconv.AppendFloat(b.data, value, formatter, precision, 64)
}
func (b *Buffer) WriteComplexStr(value complex128, formatter byte, precision int) {
b.lastOp = opInvalid
if formatter == 0 {
@ -82,3 +76,7 @@ func (b *Buffer) WriteComplexStr(value complex128, formatter byte, precision int
}
b.data = append(b.data, strconv.FormatComplex(value, formatter, precision, 128)...)
}

@ -33,16 +33,16 @@ const(
var (
G = struct {
ErrInvalidName Err
ErrDuplicated Err
ErrFixed Err
ErrReadOnly Err
ErrInvalidName ErrBField
ErrDuplicated ErrBField
ErrFixed ErrBField
ErrReadOnly ErrBField
}{
ErrInvalidName: Err{ errs.ErrCode("invalid-name")},
ErrDuplicated : Err{ errs.ErrCode("duplicated-field")},
ErrFixed : Err{ errs.ErrCode("bfields-fixed")},
ErrReadOnly : Err{ errs.ErrCode("bfields-read-only")},
ErrInvalidName: ErrBField{errs.ErrCode("invalid-name")},
ErrDuplicated : ErrBField{errs.ErrCode("duplicated-field")},
ErrFixed : ErrBField{errs.ErrCode("bfields-fixed")},
ErrReadOnly : ErrBField{errs.ErrCode("bfields-read-only")},
}
)

@ -27,6 +27,6 @@ import "errs"
type (
Err struct { errs.ErrCode }
ErrBField struct { errs.ErrCode }
)

@ -0,0 +1,71 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name active.go
// Created by DEV
// Modified 21/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package cjson
import "unicode/utf8"
var (
G = struct {
Hex string
JSONChars [utf8.RuneSelf]CharAtt
NullValue []byte
ZeroValue []byte
TrueValue []byte
FalseValue []byte
FloatNaN []byte
FloatInfPos []byte
FloatInfNeg []byte
} {
Hex: "0123456789abcdef",
JSONChars: initJSONChars(),
NullValue: []byte{'n', 'u', 'l', 'l'},
ZeroValue: []byte{'0'},
TrueValue: []byte{'"','t', 'r', 'u', 'e','"'},
FalseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'},
FloatNaN: []byte{'"', 'N', 'a', 'N', '"'},
FloatInfPos: []byte{'"', 'I', 'n', 'f', '"'},
FloatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'},
}
)
func initJSONChars() [utf8.RuneSelf]CharAtt {
var tb = [utf8.RuneSelf]CharAtt{
'"': CharAttAllUnsafe,
'&': CharAttHtmlUnsafe,
'<': CharAttHtmlUnsafe,
'>': CharAttHtmlUnsafe,
'\\': CharAttAllUnsafe,
}
for i := 0; i <= 31; i++ {
tb[i] = CharAttAllUnsafe
}
return tb
}

@ -0,0 +1,45 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name char_att.go
// Created by DEV
// Modified 21/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package cjson
const (
CharAttUnsafe CharAtt = 1 << iota
CharAttHtmlUnsafe
CharAttAllUnsafe = CharAttUnsafe | CharAttHtmlUnsafe
)
type CharAtt uint8
func (a CharAtt) IsUnsafe() bool {
return a&CharAttUnsafe != 0 }
func (a CharAtt) IsHtmlUnsafe() bool {
return a&CharAttHtmlUnsafe != 0 }

@ -0,0 +1,257 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name writer.go
// Created by DEV
// Modified 21/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package cjson
import (
"bins/bfers"
"encoding/base32"
"encoding/base64"
"math"
"strconv"
"time"
"unicode/utf8"
)
func WriteString(b *bfers.Buffer, value string, escapeHTML bool ) {
if len(value) == 0 {
b.Write2Byte('"', '"')
return
}
b.WriteByte('"')
start := 0
for i := 0; i < len(value); {
if ch := value[i]; ch < utf8.RuneSelf {
if !G.JSONChars[ch].IsHtmlUnsafe() || (!escapeHTML && !G.JSONChars[ch].IsUnsafe()) {
i++
continue
}
if start < i {
b.WriteString(value[start:i])
}
b.WriteByte('\\')
switch ch {
case '\\', '"':
b.WriteByte(ch)
case '\n':
b.WriteByte('n')
case '\r':
b.WriteByte('r')
case '\t':
b.WriteByte('t')
default:
b.WriteString(`u00`)
b.Write2Byte(G.Hex[ch>>4], G.Hex[ch&0xF])
}
i++
start = i
continue
}
c, size := utf8.DecodeRuneInString(value[i:])
if c == utf8.RuneError && size == 1 {
if start < i {
b.WriteString(value[start:i])
}
b.WriteString(`\ufffd`)
i += size
start = i
continue
}
if c == '\u2028' || c == '\u2029' {
if start < i {
b.WriteString(value[start:i])
}
b.WriteString(`\u202`)
b.WriteByte(G.Hex[c&0xF])
i += size
start = i
continue
}
i += size
}
if start < len(value) {
b.WriteString(value[start:])
}
b.WriteByte('"')
}
func WriteUint (b *bfers.Buffer, value uint64 , quoted bool) {
if quoted {
b.WriteByte('"')
}
if value == 0 {
b.WriteByte('0')
} else {
b.WriteUIntStr(value, 10)
}
if quoted {
b.WriteByte('"')
}
}
func WriteBool (b *bfers.Buffer, value bool , quoted bool) {
if value {
b.WOQ(quoted,'"', G.TrueValue)
} else {
b.WOQ(quoted,'"', G.FalseValue)
}
}
func WriteInt (b *bfers.Buffer, value int64 , quoted bool) {
if quoted {
b.WriteByte('"')
}
if value == 0 {
b.WriteByte('0')
} else {
b.WriteIntStr(value, 10)
}
if quoted {
b.WriteByte('"')
}
}
func WriteFloat (b *bfers.Buffer, f float64, bits int, quoted bool) {
var t [64]byte
if math.IsInf(f, 0) || math.IsNaN(f) {
_,_ = b.Write(G.FloatNaN)
return
}
abs := math.Abs(f)
fm := byte('f')
if abs != 0 {
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
fm = 'e'
}
}
bf := t[:0]
bf = strconv.AppendFloat(bf, f, fm, -1, int(bits))
if fm == 'e' {
// clean up e-09 to e-9
n := len(bf)
if n >= 4 && bf[n-4] == 'e' && bf[n-3] == '-' && bf[n-2] == '0' {
bf[n-2] = bf[n-1]
bf = bf[:n-1]
}
}
b.WOQ(quoted,'"',bf)
}
func WriteDate(b *bfers.Buffer, value time.Time, layout string) {
var t [64]byte
if layout == "" {
layout = time.RFC3339
}
b.WOQ(true,'"',value.AppendFormat(t[:0],layout))
}
func WriteBinary64 (b *bfers.Buffer, value []byte) (er error) {
if value == nil {
_,_ = b.Write(G.NullValue)
return nil
}
if len(value) == 0 {
b.Write2Byte('"','"')
return nil
}
p := b.Len()
b.WriteByte('"')
var t [64]byte
ln := base64.StdEncoding.EncodedLen(len(value))
if ln <= len(t) {
dst := t[:ln]
base64.StdEncoding.Encode(dst, value)
_,er = b.Write(dst)
} else if ln <= 1024 {
dst := make([]byte, ln)
base64.StdEncoding.Encode(dst, value)
_,er = b.Write(dst)
} else if er == nil {
ec := base64.NewEncoder(base64.StdEncoding, b)
_,_ = ec.Write(value)
er = ec.Close()
}
if er == nil {
b.WriteByte('"')
} else {
b.Truncate(p)
}
return er
}
func WriteBinary32 (b *bfers.Buffer, value []byte) (er error) {
if value == nil {
_,_ = b.Write(G.NullValue)
return nil
}
if len(value) == 0 {
b.Write2Byte('"','"')
return nil
}
p := b.Len()
b.WriteByte('"')
var t [64]byte
ln := base32.StdEncoding.EncodedLen(len(value))
if ln <= len(t) {
dst := t[:ln]
base32.StdEncoding.Encode(dst, value)
_,er = b.Write(dst)
} else if ln <= 1024 {
dst := make([]byte, ln)
base32.StdEncoding.Encode(dst, value)
_,er = b.Write(dst)
} else if er == nil {
ec := base32.NewEncoder(base32.StdEncoding, b)
_,_ = ec.Write(value)
return ec.Close()
}
if er == nil {
b.WriteByte('"')
} else {
b.Truncate(p)
}
return nil
}

@ -0,0 +1,3 @@
module cdcs
go 1.22

@ -50,7 +50,7 @@ const (
var (
g = struct {
mux sync.RWMutex
mux sync.RWMutex
typeCollectors map[reflect.Type]ErrorCollector
defaultCollectors FieldCollectors
@ -104,7 +104,7 @@ func CollectErrorFields (collector Collector, err error) {
func defaultCollectors () FieldCollectors {
return []FieldCollector {
return []FieldCollector{
CollectFieldFnc(func (b Collector, e error ) bool {
if ms,is := e.(interface { Message() string }); is {

@ -36,8 +36,8 @@ type (
ErrorCollection struct {
Err error
ErrStr string
Types []reflect.Type
Fields Fields
Types []reflect.Type
Fields Fields
Causes []ErrorCollection
Trace stack.Trace
@ -63,7 +63,6 @@ func (c *ErrorCollection) Collect (addFields,addCauses,addTrace bool) *ErrorColl
func (c *ErrorCollection) collect (addFields,addCauses,addTrace bool) *ErrorCollection {
d := false
ne := c.Err
defer func(ec *ErrorCollection, dn *bool){
@ -74,6 +73,7 @@ func (c *ErrorCollection) collect (addFields,addCauses,addTrace bool) *ErrorColl
} else {
ec.Invalid = fmt.Errorf("%#v",rc)
}
}
}
}(c,&d)
@ -115,6 +115,7 @@ func (c *ErrorCollection) collect (addFields,addCauses,addTrace bool) *ErrorColl
c.Trace = tc.StackTrace()
addTrace = c.Trace == nil
}
}
// next error

@ -27,9 +27,9 @@ package collr
type (
FieldHead struct {
Name string
Kind FieldKind
Pos int
Name string
Kind FieldKind
Pos int
}
)

@ -26,7 +26,7 @@ package collr
const (
FieldKindAny FieldKind = iota
FieldKindAny FieldKind = iota
FieldKindString
FieldKindInt
FieldKindFloat

@ -47,32 +47,32 @@ type (
func (f *Fields) AddFieldAny (name string, value any) {
f.addField(name,FieldKindAny).anys = append(f.anys,value) }
f.addField(name, FieldKindAny).anys = append(f.anys,value) }
func (f *Fields) AddFieldString(name string, value string) {
f.addField(name,FieldKindString)
f.addField(name, FieldKindString)
f.strings = append(f.strings, value)
}
func (f *Fields) AddFieldInt (name string, value int) {
f.addField(name,FieldKindInt).ints = append(f.ints, value) }
f.addField(name, FieldKindInt).ints = append(f.ints, value) }
func (f *Fields) AddFieldBool (name string, value bool) {
bv := 0
if value {
bv = 1
}
f.addField(name,FieldKindInt).ints = append(f.ints, bv)
f.addField(name, FieldKindInt).ints = append(f.ints, bv)
}
func (f *Fields) AddFieldFloat (name string, value float64) {
f.addField(name,FieldKindFloat).floats = append(f.floats, value) }
f.addField(name, FieldKindFloat).floats = append(f.floats, value) }
func (f *Fields) AddFieldTime (name string, value time.Time) {
f.addField(name,FieldKindTime).dates = append(f.dates, value) }
f.addField(name, FieldKindTime).dates = append(f.dates, value) }
func (f *Fields) AddFieldDate (name string, value time.Time) {
f.addField(name,FieldKindDate).dates = append(f.dates, value) }
f.addField(name, FieldKindDate).dates = append(f.dates, value) }
@ -81,12 +81,12 @@ func (f *Fields) addField (name string, kind FieldKind) *Fields {
var pos int
switch kind {
case FieldKindBool,
FieldKindInt : pos = len(f.ints)
FieldKindInt: pos = len(f.ints)
case FieldKindString: pos = len(f.strings)
case FieldKindDate,
FieldKindTime : pos = len(f.dates)
case FieldKindFloat : pos = len(f.floats)
case FieldKindAny : pos = len(f.anys)
FieldKindTime: pos = len(f.dates)
case FieldKindFloat: pos = len(f.floats)
case FieldKindAny: pos = len(f.anys)
}
f.heads = append(f.heads, &FieldHead{
Name: name,

@ -23,26 +23,21 @@
package fjson
import "sync"
var (
G = struct {
g = struct {
buildDefault sync.Once
formatter *JSONFormatter
}{}
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'},
}
)
func DefaultFormatter () *JSONFormatter {
g.buildDefault.Do(func() {
g.formatter = NewJSONFormatter()
})
return g.formatter
}

@ -25,11 +25,11 @@ package fjson
import (
"bins/bfers"
"cdcs/cjson"
"encoding/json"
"errs/fmtr/collr"
"strconv"
collr2 "errs/collr"
"fmt"
"strings"
"time"
)
@ -37,10 +37,11 @@ type (
jsonBuilder struct {
f *JSONFormatter
b bfers.Buffer
indent string
b *bfers.Buffer
encoder *json.Encoder
sep string
pretty bool
invalid error
}
)
@ -48,13 +49,12 @@ type (
func newJsonBuilder (f *JSONFormatter) *jsonBuilder {
sep := ":"
if f.UseSpace() {
if f.UseSpace() && f.ShowPretty() {
sep = ": "
}
return &jsonBuilder{
f : f,
b : *bfers.NewBuffer(),
indent : f.indent,
b : bfers.NewBuffer(),
pretty : f.ShowPretty(),
sep : sep,
}
@ -63,28 +63,64 @@ func newJsonBuilder (f *JSONFormatter) *jsonBuilder {
func (b *jsonBuilder) format (err error) {
cl := collr.NewErrorCollection(err)
cl := collr2.NewErrorCollection(err)
cl.Collect(b.f.AddFields(),b.f.AddCauses(),b.f.AddTrace())
b.write(cl,"",false)
if cl.Invalid != nil {
b.writeFormatError(cl.Invalid)
return
}
b.write(cl,false, 0)
}
func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont bool) {
in := ""
func (b *jsonBuilder) write (coll *collr2.ErrorCollection, cont bool, level int) {
if b.invalid != nil {
return
}
d := false
defer func(dn *bool, bl *jsonBuilder){
if !(*dn) {
if rc := recover(); rc != nil {
if er,is := rc.(error); is {
bl.invalid = er
} else {
bl.invalid = fmt.Errorf("%#v",rc)
}
bl.writeFormatError(bl.invalid)
}
}
}(&d,b)
var (
indLvl,
indObj,
ind2Obj string
)
if b.pretty {
in = indent + strings.Repeat(b.indent, 1)
if level > 0 {
indLvl = strings.Repeat(b.f.layout.Indent, 1+level)
indObj = strings.Repeat(b.f.layout.Indent, 2+level)
ind2Obj = strings.Repeat(b.f.layout.Indent, 3+level)
} else {
indObj = b.f.layout.Indent
ind2Obj = strings.Repeat(b.f.layout.Indent,2)
}
if !cont {
b.b.WriteString(indent)
b.b.WriteString(indLvl)
}
}
b.b.WriteByte('{')
if b.pretty {
b.b.WriteByte('\n')
}
b.writeField("error",coll.ErrStr,in,true,false, false)
b.writeField("error",coll.ErrStr, indObj,true,false, false)
if b.f.AddTypes() {
@ -96,13 +132,13 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
}
if len(types) == 1 {
b.writeField("type", types[0].String(), in, true, false,false)
b.writeField("type", types[0].String(), indObj, true, false,false)
} else {
b.writeOpen("types", in, '[', b.pretty)
b.writeOpen("types", indObj, '[', b.pretty)
for i, t := range coll.Types {
if b.pretty {
b.b.WriteString(in)
b.b.WriteString(b.indent)
b.b.WriteString(ind2Obj)
}
b.b.WriteByte('"')
b.b.WriteString(t.String())
@ -115,7 +151,7 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
}
}
b.writeClose(in, ']')
b.writeClose(indObj, ']')
}
}
@ -129,12 +165,9 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
}
coll.Fields.Sort()
b.writeOpen("fields", in, '{', b.pretty)
b.writeOpen("fields", indObj, '{', b.pretty)
var n = 0
var fi string
if b.pretty {
fi = in + b.indent
}
for _, h := range heads {
p := b.b.Len()
@ -145,9 +178,9 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
}
}
b.writeFieldName(h.Name,fi)
b.writeFieldName(h.Name,ind2Obj)
if !b.writeFieldValue(coll.Fields, h) {
if !b.writeFieldValue(coll.Fields, h,level) {
b.b.Truncate(p)
continue
}
@ -156,7 +189,7 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
if n > 0 && b.pretty {
b.b.WriteByte('\n')
}
b.writeClose(in,'}')
b.writeClose(indObj,'}')
}
causes := coll.Causes
@ -168,14 +201,10 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
}
if len(causes) == 1 {
b.writeOpen("cause", in, 0, false)
b.write(&causes[0], strings.Repeat(b.indent, 1), true)
b.writeOpen("cause", indObj, 0, false)
b.write(&causes[0], true,level+1)
} else if len(causes) > 1 {
b.writeOpen("causes", in, '[', b.pretty)
var ci string
if b.pretty {
ci = strings.Repeat(b.indent, 2)
}
b.writeOpen("causes", indObj, '[', b.pretty)
for i, ce := range causes {
if i > 0 {
b.b.WriteByte(',')
@ -183,20 +212,43 @@ func (b *jsonBuilder) write (coll *collr.ErrorCollection,indent string, cont boo
b.b.WriteByte('\n')
}
}
b.write(&ce, ci, false)
b.write(&ce, false,level+1)
}
if b.pretty {
b.b.WriteByte('\n')
}
b.writeClose(in, ']')
b.writeClose(indObj, ']')
}
}
if coll.Trace != nil {
p := b.b.Len()
b.b.WriteByte(',')
if b.pretty {
b.b.WriteByte('\n')
}
b.writeFieldName("stack",indObj)
if b.encoder == nil {
b.encoder = json.NewEncoder(b.b)
}
if b.pretty {
b.encoder.SetIndent(strings.Repeat(b.f.layout.Indent,level+1),b.f.layout.Indent)
}
if er := b.encoder.Encode(coll.Trace.Frames()); er != nil {
b.b.Truncate(p)
}
}
if b.pretty {
b.b.WriteByte('\n')
}
b.writeClose(indent,'}')
b.writeClose(indLvl,'}')
d= true
}
@ -211,24 +263,18 @@ func (b *jsonBuilder) writeOpen(name, indent string, object byte,nl bool) {
}
}
func (b *jsonBuilder) writeClose(indent string, object byte) {
if b.pretty {
b.b.WriteString(indent)
b.b.WriteByte(object)
} else {
b.b.WriteByte(object)
}
b.b.WriteByte(object)
}
func (b *jsonBuilder) writeFieldName (name, indent string) {
if b.pretty {
b.b.WriteString(indent)
}
b.b.WriteByte('"')
b.b.WriteString(name)
b.b.WriteByte('"')
cjson.WriteString(b.b,name,true)
b.b.WriteString(b.sep)
}
@ -250,66 +296,56 @@ func (b *jsonBuilder) writeField (name, value, indent string, quote, coma, nl bo
}
func (b *jsonBuilder) writeFieldValue (fields collr.Fields, field *collr.FieldHead) bool {
var v []byte
q := true
func (b *jsonBuilder) writeFieldValue (fields collr2.Fields, field *collr2.FieldHead, level int) bool {
switch field.Kind {
case collr.FieldKindFloat :
case collr2.FieldKindFloat:
n := fields.GetFieldValueFloat(field)
if n == 0 {
if b.f.IgnoreDefaults() {
if n == 0 && b.f.IgnoreDefaults() {
return false
}
v = g.zero
} else {
v = strconv.AppendFloat(v, n, 'E', -1, 64)
}
cjson.WriteFloat(b.b,n,64,b.f.UseQuote())
return true
case collr.FieldKindInt :
case collr2.FieldKindInt:
n := fields.GetFieldValueInt(field)
if n == 0 {
if b.f.IgnoreDefaults() {
return false
}
v = g.zero
} else {
v = strconv.AppendInt(v, int64(n), 10)
if n == 0 && b.f.IgnoreDefaults() {
return false
}
q = b.f.UseQuote()
cjson.WriteInt(b.b,int64(n),b.f.UseQuote())
return true
case collr.FieldKindString:
case collr2.FieldKindString:
s := fields.GetFieldValueString(field)
if len(s) == 0 && b.f.IgnoreDefaults() {
return false
}
v = []byte(s)
cjson.WriteString(b.b,s,b.f.EscapeHTML())
return true
case collr.FieldKindTime :
case collr2.FieldKindTime:
d := fields.GetFieldValueDate(field)
if d.IsZero() && b.f.IgnoreDefaults(){
return false
}
v = d.AppendFormat(v,time.RFC822Z)
cjson.WriteDate(b.b,d,b.f.layout.TimeLayout)
return true
case collr.FieldKindDate :
case collr2.FieldKindDate:
d := fields.GetFieldValueDate(field)
if d.IsZero() && b.f.IgnoreDefaults() {
if d.IsZero() && b.f.IgnoreDefaults(){
return false
}
v = d.AppendFormat(v,time.RFC822Z)
cjson.WriteDate(b.b,d,b.f.layout.DateLayout)
return true
case collr.FieldKindBool :
case collr2.FieldKindBool:
t := fields.GetFieldValueBool(field)
if !t {
if b.f.IgnoreDefaults() {
return false
}
v = g.vfalse
} else {
v = g.vtrue
if !t && b.f.IgnoreDefaults() {
return false
}
q = b.f.UseQuote()
cjson.WriteBool(b.b,t,b.f.UseQuote())
return true
default:
a := fields.GetFieldValueAny(field)
@ -317,20 +353,38 @@ func (b *jsonBuilder) writeFieldValue (fields collr.Fields, field *collr.FieldHe
if b.f.IgnoreDefaults() {
return false
}
v = g.null
} else {
var e error
if v,e = json.Marshal(a); e != nil {
return false
}
b.b.WOQ(true,'"',cjson.G.NullValue)
return true
}
if b.encoder == nil {
b.encoder = json.NewEncoder(b.b)
b.encoder.SetEscapeHTML(b.f.EscapeHTML())
}
if b.pretty {
b.encoder.SetIndent(strings.Repeat(b.f.layout.Indent,level+3),b.f.layout.Indent)
}
if er := b.encoder.Encode(a); er != nil {
return false
}
return true
}
if q {
b.b.WriteByte('"')
}
_,_ = b.b.Write(v)
if q {
b.b.WriteByte('"')
}
return true
}
func (b *jsonBuilder) writeFormatError (err error) {
b.b.Reset()
b.b.WriteByte('{')
b.writeFieldName("json-formatter-error","")
cjson.WriteString(b.b,err.Error(),b.f.EscapeHTML())
b.b.WriteByte('}')
}
func (b *jsonBuilder) reset () {
b.b.Reset()
b.encoder = nil
b.invalid = nil
}

@ -23,12 +23,11 @@
package fjson
type (
JSONFormatter struct {
Option
indent string
layout Layout
}
@ -38,8 +37,8 @@ type (
func NewJSONFormatter (options ...JSONFormatterFnc) *JSONFormatter {
f := &JSONFormatter{
Option: ShowPretty |UseSpace | AddTypes |AddFields | AddCauses | AddTrace | IgnoreDefaults,
indent: " ",
Option: ShowPretty | UseSpace | AddTypes | AddFields | AddCauses | AddTrace | IgnoreDefaults,
layout: *newLayout(),
}
for _,o := range options {
o(f)
@ -49,12 +48,26 @@ func NewJSONFormatter (options ...JSONFormatterFnc) *JSONFormatter {
func (f *JSONFormatter) FormatError (err error) []byte {
if err == nil {
return nil
}
b := newJsonBuilder (f)
b := newJsonBuilder(f)
defer func(bl *jsonBuilder){
bl.b.Reset()
bl.reset()
}(b)
b.format(err)
return b.b.Bytes()
}
func WithLayout (config LayoutFnc) JSONFormatterFnc {
return func(f *JSONFormatter) {
config(&f.layout) } }
func WithOptions (set, unset Option) JSONFormatterFnc {
return func(f *JSONFormatter) {
f.Option |= set
f.Option &^= unset } }

@ -0,0 +1,50 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name Layout.go
// Created by DEV
// Modified 13/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package fjson
import (
"time"
)
type (
Layout struct {
Indent string
TimeLayout string
DateLayout string
}
LayoutFnc func (layouts *Layout)
)
func newLayout () *Layout {
return &Layout{
Indent: " ",
DateLayout: time.RFC3339,
TimeLayout: time.TimeOnly,
}
}

@ -37,6 +37,7 @@ const (
UseQuote
IgnoreDefaults
SortFields
EscapeHTML
)
@ -72,3 +73,6 @@ func (o Option) SortFields () bool {
func (o Option) IgnoreDefaults() bool {
return o&IgnoreDefaults != 0 }
func (o Option) EscapeHTML() bool {
return o&EscapeHTML != 0 }

@ -0,0 +1,66 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name active.go
// Created by DEV
// Modified 22/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"errs/stack"
)
func defaultFrameBuilder (builder *TextBuilder, frame stack.Frame, num int) {
/*
if strings.Index(frame.Package,"runtime") != -1 {
return
}
var c1, c2, c3, c4 ansi.Code
if builder.Options().ShowAnsi(){
c1 = c1.SetFgColor(ansi.ColorBlue)//.SetBgColor(ansi.ColorHBlack)
c2 = c2.SetFgColor(ansi.ColorMagenta)
c3 = c3.SetFgColor(ansi.ColorWhite)
c4 = c3.SetFgColor(ansi.ColorHWhite)
}
builder.AddText(c4.Sprintf(" %d %s.%s \n",num,frame.Package, frame.FuncName))
builder.AddText(c2.Sprintf(" %.90s:%d\n", frame.File, frame.LineNumber))
f, e := frame.SourceLine()
if e == nil {
builder.AddTextAnsi(fmt.Sprintf(" %s\n", f),c3)
} else {
builder.AddTextAnsi(fmt.Sprintf(" error %s\n", e.Error()),c3)
}
*/
}
func defaultFallback (b *TextBuilder, err, cause error) {
/*
b.AddText(fmt.Sprintf("Formatter error: Cant format error type (%s)\nValue : %#v \nCause : %s\n",reflect.TypeOf(err).String(),err,cause.Error()))
*/
}

@ -0,0 +1,31 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name fallback.go
// Created by DEV
// Modified 18/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
type (
ErrorFallbackFnc func (builder *TextBuilder, err, cause error)
)

@ -0,0 +1,61 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name Layout.go
// Created by DEV
// Modified 13/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"ansi"
"time"
)
type (
Layout struct {
AnsiC ansi.Code
Indent string
FieldSep string
TimeLayout string
DateLayout string
IntLayout string
FloatLayout string
BoolLayout string
}
LayoutFnc func (layouts *Layout)
)
func newLayouts () *Layout {
return &Layout{
Indent : " ",
FieldSep : " : ",
TimeLayout : time.RFC822Z,
DateLayout : time.RFC822Z,
IntLayout : "%d",
FloatLayout : "%-10s: %.2f",
}
}

@ -0,0 +1,80 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name show.go
// Created by DEV
// Modified 07/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
const (
AddWrapped Option = 1 << iota
AddType
AddCode
AddFields
AddCause
AddTrace
ShowAnsi
UseIndent
NotShowEmpty
optionsDefault = AddWrapped | AddCode | AddType | ShowAnsi | UseIndent | AddFields | AddCause | AddTrace | NotShowEmpty
)
type (
Option uint16
)
func (o Option) SetDefaults () Option {
return optionsDefault
}
func (o Option) AddWrapped() bool {
return o&AddWrapped !=0 }
func (o Option) AddType() bool {
return o&AddType !=0 }
func (o Option) AddCode() bool {
return o&AddCode != 0 }
func (o Option) ShowAnsi () bool {
return o&ShowAnsi !=0 }
func (o Option) UseIndent() bool {
return o&UseIndent !=0 }
func (o Option) AddFields() bool {
return o&AddFields !=0 }
func (o Option) AddCause() bool {
return o&AddCause !=0 }
func (o Option) AddTrace() bool {
return o&AddTrace !=0 }
func (o Option) NotShowEmpty() bool {
return o&NotShowEmpty !=0 }

@ -0,0 +1,58 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name section.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import "ansi"
type (
section struct {
ansiC ansi.Code
beginFn func(textBuilder *TextBuilder)
endFn func(textBuilder *TextBuilder)
}
)
func (s *section) Set(ansiC ansi.Code, beginFn, endFn TextBuilderFnc) {
s.ansiC = ansiC
s.beginFn,s.endFn = beginFn,endFn }
func (s *section) begin(txtBuilder *TextBuilder) {
txtBuilder.setAnsi(s.ansiC)
if s.beginFn != nil {
s.beginFn(txtBuilder)
}
}
func (s *section) end(txtBuilder *TextBuilder) {
txtBuilder.setAnsi(s.ansiC)
if s.endFn != nil {
s.endFn(txtBuilder)
}
}

@ -0,0 +1,44 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name sections.go
// Created by DEV
// Modified 16/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
type (
Sections struct {
Main section
Head section
Fields section
Causes section
Cause section
Trace section
}
SectionsFnc func(secs *Sections)
)

@ -0,0 +1,74 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name text_builder.go
// Created by DEV
// Modified 22/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"ansi"
"bytes"
)
type (
TextBuilder struct {
f *TextFormatter
b bytes.Buffer
ansiC ansi.Code
invalid error
}
TextBuilderFnc func (b *TextBuilder)
)
func newTextBuilder(formatter *TextFormatter) *TextBuilder {
return &TextBuilder{
f : formatter,
ansiC: formatter.layout.AnsiC}}
func (s *TextBuilder) format (err error) {}
func (s *TextBuilder) setAnsi(ansiC ansi.Code) {
if ansiC != 0 {
s.ansiC = ansiC
} else {
s.ansiC = s.f.layout.AnsiC
}
}
func (s *TextBuilder) reset () {
s.b.Reset()
s.f = nil
s.invalid = nil
}

@ -0,0 +1,128 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name text_formatter.go
// Created by DEV
// Modified 22/04/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package ftext
import (
"errs/stack"
"tbase/astrings"
)
type (
TextFormatter struct {
Option
layout Layout
sections Sections
nameTrans astrings.Transformers
valueTrans astrings.Transformers
onFormatError ErrorFallbackFnc
onTraceError ErrorFallbackFnc
onCauseError ErrorFallbackFnc
frameBuilder func (builder *TextBuilder, frame stack.Frame, num int)
}
TextFormatterFnc func (formatter *TextFormatter)
)
func NewTextFormatter(options ...TextFormatterFnc) *TextFormatter {
fm := &TextFormatter{
Option : optionsDefault,
layout : *newLayouts(),
frameBuilder : defaultFrameBuilder,
onFormatError : defaultFallback,
onTraceError : defaultFallback,
onCauseError : defaultFallback,
}
for _,o := range options {
o(fm)
}
return fm
}
func (f *TextFormatter) FormatError (err error) []byte {
b := newTextBuilder(f)
defer func(tb *TextBuilder){
tb.reset()
}(b)
b.format(err)
return b.b.Bytes()
}
func WithErrorFallbacks (format, cause, trace ErrorFallbackFnc) TextFormatterFnc {
return func(f *TextFormatter) {
if format == nil {
f.onFormatError = format
}
if cause == nil {
f.onCauseError = cause
}
if trace == nil {
f.onTraceError = trace
}
}
}
func WithOptions (set, unset Option) TextFormatterFnc {
return func(f *TextFormatter) {
f.Option |= set
f.Option &^= unset } }
func WithNameTransformers(transformer ...astrings.Transformer) TextFormatterFnc {
return func(f *TextFormatter) {
f.nameTrans = append(f.nameTrans, transformer ...) } }
func WithValueTransformers(transformer ...astrings.Transformer) TextFormatterFnc {
return func(f *TextFormatter) {
f.valueTrans = append(f.nameTrans, transformer ...) } }
func WithSectionsFormat(config SectionsFnc) TextFormatterFnc {
return func(f *TextFormatter) {
config(&f.sections) } }
func WithLayouts (config LayoutFnc) TextFormatterFnc {
return func(f *TextFormatter) {
config(&f.layout) } }
func WithFrameBuilder (builderFn func (builder *TextBuilder, frame stack.Frame, num int)) TextFormatterFnc {
return func(f *TextFormatter) {
f.frameBuilder = builderFn } }

@ -24,9 +24,8 @@
package errs
import (
collr2 "errs/collr"
"errs/fmtr"
"errs/fmtr/collr"
)
type (
@ -78,6 +77,6 @@ func (e ErrCode) BuildFormat(builder fmtr.Builder) {
builder.Build(e,nil) }
func (e ErrCode) Collect (collector collr.Collector) {
collector.AddFieldString(collr.FieldNameCode,string(e))
func (e ErrCode) Collect (collector collr2.Collector) {
collector.AddFieldString(collr2.FieldNameCode,string(e))
}

@ -24,8 +24,8 @@
package errs
import (
collr2 "errs/collr"
"errs/fmtr"
"errs/fmtr/collr"
"fmt"
"time"
)
@ -118,10 +118,10 @@ func (e ErrInfo) BuildFormat(builder fmtr.Builder) {
}
func (e ErrInfo) Collect (collector collr.Collector) {
collector.AddFieldString(collr.FieldNameMessage,e.message)
collector.AddFieldString(collr.FieldNameInfo,e.info)
collector.AddFieldDate (collr.FieldNameDate,e.date)
func (e ErrInfo) Collect (collector collr2.Collector) {
collector.AddFieldString(collr2.FieldNameMessage,e.message)
collector.AddFieldString(collr2.FieldNameInfo,e.info)
collector.AddFieldDate (collr2.FieldNameDate,e.date)
if len(e.metas) > 0 {
for n,v := range e.metas {
collector.AddFieldString(n,v)

@ -24,14 +24,12 @@
package pjson
import (
"encoding"
"encoding/json"
"packs"
"reflect"
"rsts"
"sync"
"unicode/utf8"
)
@ -48,67 +46,25 @@ const (
var (
g = struct {
hex string
jsonChars [utf8.RuneSelf]jsonCharAtt
nullValue []byte
zeroValue []byte
trueValue []byte
falseValue []byte
floatNaN []byte
floatInfPos []byte
floatInfNeg []byte
packersCache sync.Map
keyersCache sync.Map
fieldsCache sync.Map
packersCache sync.Map
keyersCache sync.Map
fieldsCache sync.Map
jsonMarshalerType reflect.Type
textMarshalerType reflect.Type
packMarshalerType reflect.Type
jsonMarshalerType reflect.Type
textMarshalerType reflect.Type
packMarshalerType reflect.Type
}{
hex: "0123456789abcdef",
jsonChars: initJSONChars(),
nullValue: []byte{'n', 'u', 'l', 'l'},
zeroValue: []byte{'0'},
trueValue: []byte{'"','t', 'r', 'u', 'e','"'},
falseValue: []byte{'"','f', 'a', 'l', 's', 'e','"'},
floatNaN: []byte{'"', 'N', 'a', 'N', '"'},
floatInfPos: []byte{'"', 'I', 'n', 'f', '"'},
floatInfNeg: []byte{'"', '-', 'I', 'n', 'f', '"'},
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
packMarshalerType: reflect.TypeOf((*pkrs.Packer)(nil)).Elem(),
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
packMarshalerType: reflect.TypeOf((*pkrs.Packer)(nil)).Elem(),
}
)
func initJSONChars() [utf8.RuneSelf]jsonCharAtt {
var tb = [utf8.RuneSelf]jsonCharAtt{
'"': jsonCharAttAllUnsafe,
'&': jsonCharAttHtmlUnsafe,
'<': jsonCharAttHtmlUnsafe,
'>': jsonCharAttHtmlUnsafe,
'\\': jsonCharAttAllUnsafe,
}
for i := 0; i <= 31; i++ {
tb[i] = jsonCharAttAllUnsafe
}
return tb
}
func Pack (value any, options ...JSONPackerFnc) (res rsts.Bytes) {
p := NewJSONPacker(options ...)
p.Pack(value,defaultFlags)

@ -1,41 +0,0 @@
// ------------------------------------------------------------------------
// Project atila
// Active Thing (activething.com) git.activething.com/go
//
// File name json_char_atts.go
// Created by DEV
// Modified 18/01/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
package pjson
const (
jsonCharAttUnsafe jsonCharAtt = 1 << iota
jsonCharAttHtmlUnsafe
jsonCharAttAllUnsafe = jsonCharAttUnsafe | jsonCharAttHtmlUnsafe
)
type jsonCharAtt uint8
func (a jsonCharAtt) isUnsafe() bool {
return a&jsonCharAttUnsafe != 0
}
func (a jsonCharAtt) isHtmlUnsafe() bool {
return a&jsonCharAttHtmlUnsafe != 0
}

@ -24,17 +24,13 @@
package pjson
import (
"cdcs/cjson"
"crypts"
"encoding/base32"
"encoding/base64"
"encoding/json"
"errs"
"math"
"packs"
"reflect"
"strconv"
"time"
"unicode/utf8"
)
@ -105,7 +101,7 @@ func (p *JSONPacker) PackAny (value any, flags pkrs.Flags) {
panic(pkrs.G.ErrInvalidState.WrapWithCause(p.state.Error))
}
if value == nil {
p.state.W(g.nullValue)
p.state.W(cjson.G.NullValue)
return
}
@ -216,7 +212,7 @@ func (p *JSONPacker) packCompound (opener, closer byte, isnil bool, buildFn func
panic(pkrs.G.ErrInvalidState.WrapWithCause(p.state.Error))
}
if isnil {
p.state.W(g.nullValue)
p.state.W(cjson.G.NullValue)
return
}
@ -243,7 +239,7 @@ func packRaw (state *pkrs.State, value []byte, flags pkrs.Flags) {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
if value == nil {
state.W(g.nullValue)
state.W(cjson.G.NullValue)
return
}
if len(value) == 0 {
@ -273,12 +269,13 @@ func packString (state *pkrs.State, value string , flags pkrs.Flags) {
return
}
cjson.WriteString(state.Buffer,value,flags.EscapeHTML())
/*
state.WriteByte('"')
start := 0
for i := 0; i < len(value); {
if b := value[i]; b < utf8.RuneSelf {
if !g.jsonChars[b].isHtmlUnsafe() || (!flags.EscapeHTML() && !g.jsonChars[b].isUnsafe()) {
if !cjson.G.JSONChars[b].IsHtmlUnsafe() || (!flags.EscapeHTML() && !cjson.G.JSONChars[b].IsUnsafe()) {
i++
continue
}
@ -294,7 +291,7 @@ func packString (state *pkrs.State, value string , flags pkrs.Flags) {
case '\t': state.WriteByte('t')
default:
state.WriteString(`u00`)
state.Write2Byte(g.hex[b>>4], g.hex[b&0xF])
state.Write2Byte(cjson.G.Hex[b>>4], cjson.G.Hex[b&0xF])
}
i++
start = i
@ -316,7 +313,7 @@ func packString (state *pkrs.State, value string , flags pkrs.Flags) {
state.WriteString(value[start:i])
}
state.WriteString(`\u202`)
state.WriteByte(g.hex[c&0xF])
state.WriteByte(cjson.G.Hex[c&0xF])
i += size
start = i
continue
@ -327,6 +324,8 @@ func packString (state *pkrs.State, value string , flags pkrs.Flags) {
state.WriteString(value[start:])
}
state.WriteByte('"')
*/
}
@ -337,6 +336,12 @@ func packEncrypted (state *pkrs.State, value []byte, flags pkrs.Flags) {
return
}
if !flags.Binary() {
flags|=pkrs.FlagBinary64
}
packBinary(state,value,flags)
/*
state.WriteByte('"')
if flags.Bin64() || !flags.Binary() {
packBinary64(state, r.Value(), flags)
@ -347,6 +352,8 @@ func packEncrypted (state *pkrs.State, value []byte, flags pkrs.Flags) {
state.WriteByte('"')
}
return
*/
}
func packBinary (state *pkrs.State, value []byte , flags pkrs.Flags) {
@ -354,8 +361,9 @@ func packBinary (state *pkrs.State, value []byte , flags pkrs.Flags) {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
/*
if value == nil {
_,_ = state.Write(g.nullValue)
_,_ = state.Write(cjson.G.NullValue)
return
}
if len(value) == 0 {
@ -363,11 +371,26 @@ func packBinary (state *pkrs.State, value []byte , flags pkrs.Flags) {
return
}
if flags.Encrypted() {
packEncrypted(state,value,flags)
return
}
*/
if flags.Bin64() {
state.SetError(cjson.WriteBinary64(state.Buffer,value))
return
}
if flags.Bin32() {
state.SetError(cjson.WriteBinary32(state.Buffer,value))
return
}
state.SetError(pkrs.G.ErrUnsupportedType)
/*
state.WriteByte('"')
if flags.Bin64() {
packBinary64(state, value, 0)
@ -380,9 +403,10 @@ func packBinary (state *pkrs.State, value []byte , flags pkrs.Flags) {
if state.Error == nil {
state.WriteByte('"')
}
*/
}
/*
func packBinary64 (state *pkrs.State, value []byte , _ pkrs.Flags) {
ln := base64.StdEncoding.EncodedLen(len(value))
if ln <= len(state.Temp) {
@ -417,25 +441,32 @@ func packBinary32 (state *pkrs.State, value []byte , _ pkrs.Flags) {
}
}
*/
func packBool (state *pkrs.State, value bool , flags pkrs.Flags) {
if state.Error != nil {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
cjson.WriteBool(state.Buffer,value,flags.Quote())
/*
if value {
state.WOQ(flags.Quote(),'"', g.trueValue)
state.WOQ(flags.Quote(),'"', cjson.G.TrueValue)
} else {
state.WOQ(flags.Quote(),'"', g.falseValue)
state.WOQ(flags.Quote(),'"', cjson.G.FalseValue)
}
*/
}
func packInt (state *pkrs.State, value int64 , flags pkrs.Flags) {
if state.Error != nil {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
cjson.WriteInt(state.Buffer,value,flags.Quote())
/*
q :=flags.Quote()
if q {
state.WriteByte('"')
@ -448,6 +479,7 @@ func packInt (state *pkrs.State, value int64 , flags pkrs.Flags) {
if q {
state.WriteByte('"')
}
*/
}
@ -455,6 +487,9 @@ func packUInt (state *pkrs.State, value uint64 , flags pkrs.Flags) {
if state.Error != nil {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
cjson.WriteUint(state.Buffer,value,flags.Quote())
/*
q :=flags.Quote()
if q {
state.WriteByte('"')
@ -467,6 +502,8 @@ func packUInt (state *pkrs.State, value uint64 , flags pkrs.Flags) {
if q {
state.WriteByte('"')
}
*/
}
func packFloat (state *pkrs.State, value float64, flags pkrs.Flags) {
@ -477,7 +514,9 @@ func packFloatString (state *pkrs.State, f float64, flags pkrs.Flags, bits int)
if state.Error != nil {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
cjson.WriteFloat(state.Buffer,f,bits,flags.Quote())
/*
if math.IsInf(f, 0) || math.IsNaN(f) {
state.SetError(pkrs.G.ErrInvalidValue)
return
@ -503,6 +542,8 @@ func packFloatString (state *pkrs.State, f float64, flags pkrs.Flags, bits int)
}
state.WOQ(flags.Quote(),'"',bf)
*/
}
@ -510,7 +551,8 @@ func packDate(state *pkrs.State, value time.Time, flags pkrs.Flags) {
if state.Error != nil {
panic(pkrs.G.ErrInvalidState.WrapWithCause(state.Error))
}
state.WOQ(true,'"',value.AppendFormat(state.Temp[:0],flags.DateFormat()))
cjson.WriteDate(state.Buffer,value,flags.DateFormat())
//state.WOQ(true,'"',value.AppendFormat(state.Temp[:0],flags.DateFormat()))
}

@ -24,13 +24,14 @@
package pjson
import (
"cdcs/cjson"
"packs"
"reflect"
)
func rInterfacePacker (s *pkrs.State, v reflect.Value, f pkrs.Flags) {
if v.IsNil() {
s.W(g.nullValue)
s.W(cjson.G.NullValue)
return
}
rValuePacker(v.Elem())(s,v,f)

@ -24,6 +24,7 @@
package pjson
import (
"cdcs/cjson"
"packs"
"reflect"
)
@ -79,7 +80,7 @@ func (p rList) packBinarySlice (s *pkrs.State, v reflect.Value, f pkrs.Flags) {
func (p rList) packSlice(s *pkrs.State, v reflect.Value, f pkrs.Flags) {
if v.IsNil() {
s.W(g.nullValue)
s.W(cjson.G.NullValue)
return
}
@ -106,7 +107,7 @@ func (p rList) packSlice(s *pkrs.State, v reflect.Value, f pkrs.Flags) {
func (p rList) pack (s *pkrs.State, v reflect.Value, f pkrs.Flags) {
if v.IsNil() {
s.W(g.nullValue)
s.W(cjson.G.NullValue)
return
}

@ -24,6 +24,7 @@
package pjson
import (
"cdcs/cjson"
"packs"
"reflect"
"sort"
@ -59,7 +60,7 @@ func (p *rMap) pack (s *pkrs.State, v reflect.Value, f pkrs.Flags) {
}
if v.IsNil() {
s.W(g.nullValue)
s.W(cjson.G.NullValue)
return
}
if v.Len() == 0 {

@ -24,6 +24,7 @@
package pjson
import (
"cdcs/cjson"
"packs"
"reflect"
)
@ -48,7 +49,7 @@ func newRPointer (rtype reflect.Type) *rPointer {
func (p rPointer) pack (s *pkrs.State, v reflect.Value, f pkrs.Flags) {
if v.IsNil() {
s.W(g.nullValue)
s.W(cjson.G.NullValue)
return
}
s.Level++

@ -4,6 +4,7 @@ use (
./core/errs
./core/rsts
./core/cdcs
./core/crypts
./core/vals
./core/btes

Loading…
Cancel
Save

Powered by TurnKey Linux.