incluidas las librerias de transformacion de strings

master
DEV 3 years ago
parent 16088c88b5
commit d96d15cb9b

@ -1,7 +1,6 @@
package main
import (
"bytes"
"errs"
"fmt"
)
@ -19,20 +18,29 @@ type (
MiCustomErr struct {
error
Link string
ms string
}
)
func (c MiCustomErr) Message() string {
return "esto es un custom werro"
}
/*
func fm (b *bytes.Buffer, e error, l int) {
b.WriteString("Link :"+e.(MiCustomErr).Link+"\n")
}
*/
func (m MiCustomErr) Unwrap () error {
return m.error
}
func main() {
ercode := errs.ErrCode("error->err-code")
@ -51,6 +59,10 @@ func main() {
fmt.Print(erInfo.String())
fmt.Print("\n")
fmt.Print(string(errs.G.Formatter.Format(&MiCustomErr{error:errs.ErrCode("UnErrorCU") })))
fmt.Print("\n")
/*
ertrace := errs.ErrCode("err-code-with-trace").ToErrTrace(0)
fmt.Print(ertrace.String())

@ -2,9 +2,9 @@
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name string.go
// File name active.go
// Created by DEV
// Modified 29/03/2024
// Modified 31/03/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
@ -21,22 +21,24 @@
// limitations under the License.
// ------------------------------------------------------------------------
package typex
package astrings
import "sync"
var (
G = struct {
uppercaseAcronym sync.Map
} {
func SplitString (source string, size int) []string {
var lines []string
for i := 0; i < len(source); i += size {
// Calcula el tamaño máximo para el fragmento actual
remaining := len(source) - i
fragmentSize := min(size, remaining)
line := source[i : i+fragmentSize]
lines = append(lines, line)
}
return lines
}
)
func AddAcronym (key, val string) {
G.uppercaseAcronym.Store(key, val)
}

@ -0,0 +1,88 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name camel.go
// Created by DEV
// Modified 31/03/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.
// ------------------------------------------------------------------------
// https://github.com/iancoleman/strcase/blob/v0.3.0/camel.go
package astrings
import (
"strings"
)
// Converts a string to CamelCase
func toCamelInitCase(s string, initCase bool) string {
s = strings.TrimSpace(s)
if s == "" {
return s
}
a, hasAcronym := G.uppercaseAcronym.Load(s)
if hasAcronym {
s = a.(string)
}
n := strings.Builder{}
n.Grow(len(s))
capNext := initCase
prevIsCap := false
for i, v := range []byte(s) {
vIsCap := v >= 'A' && v <= 'Z'
vIsLow := v >= 'a' && v <= 'z'
if capNext {
if vIsLow {
v += 'A'
v -= 'a'
}
} else if i == 0 {
if vIsCap {
v += 'a'
v -= 'A'
}
} else if prevIsCap && vIsCap && !hasAcronym {
v += 'a'
v -= 'A'
}
prevIsCap = vIsCap
if vIsCap || vIsLow {
n.WriteByte(v)
capNext = false
} else if vIsNum := v >= '0' && v <= '9'; vIsNum {
n.WriteByte(v)
capNext = true
} else {
capNext = v == '_' || v == ' ' || v == '-' || v == '.'
}
}
return n.String()
}
// ToCamel converts a string to CamelCase
func ToCamel(s string) string {
return toCamelInitCase(s, true)
}
// ToLowerCamel converts a string to lowerCamelCase
func ToLowerCamel(s string) string {
return toCamelInitCase(s, false)
}

@ -0,0 +1,117 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name snake.go
// Created by DEV
// Modified 31/03/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.
// ------------------------------------------------------------------------
// https://github.com/iancoleman/strcase/blob/v0.3.0/snake.go
package astrings
import "strings"
// ToSnake converts a string to snake_case
func ToSnake(s string) string {
return ToDelimited(s, '_')
}
func ToSnakeWithIgnore(s string, ignore string) string {
return ToScreamingDelimited(s, '_', ignore, false)
}
// ToScreamingSnake converts a string to SCREAMING_SNAKE_CASE
func ToScreamingSnake(s string) string {
return ToScreamingDelimited(s, '_', "", true)
}
// ToKebab converts a string to kebab-case
func ToKebab(s string) string {
return ToDelimited(s, '-')
}
// ToScreamingKebab converts a string to SCREAMING-KEBAB-CASE
func ToScreamingKebab(s string) string {
return ToScreamingDelimited(s, '-', "", true)
}
// ToDelimited converts a string to delimited.snake.case
// (in this case `delimiter = '.'`)
func ToDelimited(s string, delimiter uint8) string {
return ToScreamingDelimited(s, delimiter, "", false)
}
// ToScreamingDelimited converts a string to SCREAMING.DELIMITED.SNAKE.CASE
// (in this case `delimiter = '.'; screaming = true`)
// or delimited.snake.case
// (in this case `delimiter = '.'; screaming = false`)
func ToScreamingDelimited(s string, delimiter uint8, ignore string, screaming bool) string {
s = strings.TrimSpace(s)
n := strings.Builder{}
n.Grow(len(s) + 2) // nominal 2 bytes of extra space for inserted delimiters
for i, v := range []byte(s) {
vIsCap := v >= 'A' && v <= 'Z'
vIsLow := v >= 'a' && v <= 'z'
if vIsLow && screaming {
v += 'A'
v -= 'a'
} else if vIsCap && !screaming {
v += 'a'
v -= 'A'
}
// treat acronyms as words, eg for JSONData -> JSON is a whole word
if i+1 < len(s) {
next := s[i+1]
vIsNum := v >= '0' && v <= '9'
nextIsCap := next >= 'A' && next <= 'Z'
nextIsLow := next >= 'a' && next <= 'z'
nextIsNum := next >= '0' && next <= '9'
// add underscore if next letter case type is changed
if (vIsCap && (nextIsLow || nextIsNum)) || (vIsLow && (nextIsCap || nextIsNum)) || (vIsNum && (nextIsCap || nextIsLow)) {
prevIgnore := ignore != "" && i > 0 && strings.ContainsAny(string(s[i-1]), ignore)
if !prevIgnore {
if vIsCap && nextIsLow {
if prevIsCap := i > 0 && s[i-1] >= 'A' && s[i-1] <= 'Z'; prevIsCap {
n.WriteByte(delimiter)
}
}
n.WriteByte(v)
if vIsLow || vIsNum || nextIsNum {
n.WriteByte(delimiter)
}
continue
}
}
}
if (v == ' ' || v == '_' || v == '-' || v == '.') && !strings.ContainsAny(string(v), ignore) {
// replace space/underscore/hyphen/dot with delimiter
n.WriteByte(delimiter)
} else {
n.WriteByte(v)
}
}
return n.String()
}

@ -2,9 +2,9 @@
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_text.go
// File name string.go
// Created by DEV
// Modified 30/03/2024
// Modified 29/03/2024
//
// Copyright 2024 activething.com
// ------------------------------------------------------------------------
@ -21,52 +21,39 @@
// limitations under the License.
// ------------------------------------------------------------------------
package errs
package astrings
type (
FormatText struct {
options *FormatTextOps
}
import (
"strings"
)
func NewFormatText (options ...any) *FormatText {
f := &FormatText{
options: NewFormatTextOps(options...),
}
return f
func Split(source string, size int) []string {
var ls []string
for i := 0; i < len(source); i += size {
// Calcula el tamaño máximo para el fragmento actual
re := len(source) - i
fs := min(size, re)
ln := source[i : i+fs]
ls = append(ls, ln)
}
func (f *FormatText) Format (err error) []byte {
if err == nil {
return nil
return ls
}
st := newFormatTextState (f.options)
defer st.Reset()
st.format(err)
if st.error != nil {
e := st.error
//st.Reset()
st.format(e)
func Pad(source string, size int, chr byte, truncate bool) string {
cn := size - len(source)
if cn == 0 {
return source
}
return st.Bytes()
if cn < 0 {
if truncate {
return source[:size]
}
return source
}
return source + strings.Repeat(string(chr),cn)
}

@ -21,21 +21,21 @@
// limitations under the License.
// ------------------------------------------------------------------------
package typex
package astrings
type (
StringAdapter func (string) string
Transform func (string) string
StringAdapters []StringAdapter
Transformers []Transform
)
func (a StringAdapters) Apply (value string) string {
func (a Transformers) Apply (value string) string {
if len(a) == 0 {
return value
}

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

@ -25,8 +25,10 @@
package errs
import (
"atypes/astrings"
"fmt"
"reflect"
"sync"
)
@ -44,8 +46,10 @@ const (
var (
G = struct {
mux sync.RWMutex
Formatter Formatter
extractors FormatExtractors
ErrGroup ErrCode
ErrPanic ErrCode
@ -55,18 +59,10 @@ var (
ErrFormat ErrCode
ErrFormatLevel ErrCode
errCodeRT reflect.Type
errCauseRT reflect.Type
errTraceRT reflect.Type
errInfoRT reflect.Type
errPanicRT reflect.Type
errGroupRT reflect.Type
errMultiRT reflect.Type
stackTraceRType reflect.Type
}{
Formatter : NewFormatText(),
extractors : DefaultsExtractors(),
ErrGroup : ErrCode("group-error"),
ErrPanic : ErrCode("panic-error"),
@ -78,16 +74,13 @@ var (
stackTraceRType : reflect.TypeOf(StackTrace(nil)),
errCodeRT : reflect.TypeOf(ErrCode("")),
errCauseRT : reflect.TypeOf(ErrCause{}),
/*
errTraceRT : reflect.TypeOf(ErrTrace{}),
errPanicRT : reflect.TypeOf(ErrPanic{}),
errInfoRT : reflect.TypeOf(ErrInfo {}),
errGroupRT : reflect.TypeOf(ErrGroup{}),
errMultiRT : reflect.TypeOf(ErrMulti(nil)),
Formatter : NewFmtText(func (f *FmtText) {
f.FixFieldLen = 13
},
FmtTextWithNameTransformer(
astrings.ToKebab,
)),
*/
}
)
@ -173,3 +166,14 @@ func UnwrapTrace(err error) StackTrace {
}
func AddExtractors (ext ... FormatExtractor) {
G.mux.Lock()
G.extractors = append(G.extractors,ext...)
G.mux.Unlock()
}
func Extract (builder FormatBuilder, err error) {
G.mux.RLock()
G.extractors.Extract(builder,err)
G.mux.RUnlock()
}

@ -24,6 +24,7 @@
package errs
import (
"fmt"
"time"
)
@ -89,6 +90,8 @@ func (e ErrInfo) BuildFormat (builder FormatBuilder) {
builder.AddCode(e.Error())
builder.AddType("core.errs.ErrInfo")
builder.AddFieldString("Un texot a snake case ",e.message)
builder.AddFieldString("message",e.message)
builder.AddFieldString("info",e.info)
builder.AddFieldTime ("date",e.date)
@ -109,3 +112,65 @@ func (e ErrInfo) BuildFormat (builder FormatBuilder) {
func (e ErrInfo) ToErrCause (cause error) ErrCause {
return *NewErrCause(e,cause) }
func applyErrOptions(Err *ErrInfo, options ...ErrInfoFnc) *ErrInfo {
for _,o := range options {
o(Err)
}
return Err
}
func ErrInfoWithCause (cause error) ErrInfoFnc {
return func(e *ErrInfo) {
if cause == nil {
return
}
e.error = *NewErrCause(e.error,cause)
}
}
func ErrInfoWithMessage(message string, params ...any) ErrInfoFnc {
if len(params) > 0 {
message = fmt.Sprintf(message,params ...)
}
return func(e *ErrInfo) {
e.message = message
}
}
func ErrInfoWithInfo (info string, params ...any) ErrInfoFnc {
if len(params) > 0 {
info = fmt.Sprintf(info,params ...)
}
return func(e *ErrInfo) {
e.info = info
}
}
/*
func ErrInfoWithStackTrace (offset int) ErrInfoFnc {
return func (e *ErrInfo) {
e.error = *NewErrTrace(e.error,offset) }
}
*/
func ErrInfoWithMeta (name string, value string) ErrInfoFnc {
return func (e *ErrInfo) {
if e.metas == nil {
e.metas=map[string]string{name:value}
return
}
e.metas[name]=value
}
}

@ -1,87 +0,0 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name err_ops.go
// Created by DEV
// Modified 24/03/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 errs
import (
"fmt"
)
func applyErrOptions(Err *ErrInfo, options ...ErrInfoFnc) *ErrInfo {
for _,o := range options {
o(Err)
}
return Err
}
func ErrInfoWithCause (cause error) ErrInfoFnc {
return func(e *ErrInfo) {
if cause == nil {
return
}
e.error = *NewErrCause(e.error,cause)
}
}
func ErrInfoWithMessage(message string, params ...any) ErrInfoFnc {
if len(params) > 0 {
message = fmt.Sprintf(message,params ...)
}
return func(e *ErrInfo) {
e.message = message
}
}
func ErrInfoWithInfo (info string, params ...any) ErrInfoFnc {
if len(params) > 0 {
info = fmt.Sprintf(info,params ...)
}
return func(e *ErrInfo) {
e.info = info
}
}
/*
func ErrInfoWithStackTrace (offset int) ErrInfoFnc {
return func (e *ErrInfo) {
e.error = *NewErrTrace(e.error,offset) }
}
*/
func ErrInfoWithMeta (name string, value string) ErrInfoFnc {
return func (e *ErrInfo) {
if e.metas == nil {
e.metas=map[string]string{name:value}
return
}
e.metas[name]=value
}
}

@ -0,0 +1,165 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_text.go
// Created by DEV
// Modified 30/03/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 errs
import (
"atypes/astrings"
"time"
)
const (
FormatShowWrapped uint8 = 1 << iota
FormatShowType
FormatShowColors
FormatShowIndent
FormatShowDetails
FormatShowCause
FormatShowTrace
FormatShowFieldEmpty
)
type (
FmtText struct {
Show uint8
Indent string
FieldSep string
FixFieldLen int
MaxStringLen int
TimeLayout string
DateLayout string
IntLayout string
FloatLayout string
Color FmtTextColor
CodeColor FmtTextColor
FieldNameColor FmtTextColor
FieldValueColor FmtTextColor
StringTransformers astrings.Transformers
ValueTransformers astrings.Transformers
NameTransformers astrings.Transformers
}
FmtTextFnc func (fm *FmtText)
)
func NewFmtText(options ...FmtTextFnc) *FmtText {
f := &FmtText{
Indent : " ",
FieldSep : " : ",
TimeLayout : time.RFC822Z,
DateLayout : time.RFC822Z,
IntLayout : "%d",
FloatLayout: "%-10s: %.2f",
}
for _,o := range options {
o(f)
}
if f.FixFieldLen > 0 {
f.NameTransformers = append(f.NameTransformers,func(s string)string {
return astrings.Pad(s,f.FixFieldLen,' ',true)
})
}
return f
}
func (f *FmtText) Format (err error) []byte {
if err == nil {
return nil
}
st := newFmtTextState(f)
defer st.Reset()
st.format(err)
if st.error != nil {
e := st.error
//st.Reset()
st.format(e)
}
return st.Bytes()
}
func (f *FmtText) ShowWrapped () bool {
return f.Show&FormatShowWrapped !=0 }
func (f *FmtText) ShowType () bool {
return f.Show&FormatShowType !=0 }
func (f *FmtText) ShowColors () bool {
return f.Show&FormatShowColors !=0 }
func (f *FmtText) ShowIndent () bool {
return f.Show&FormatShowIndent !=0 }
func (f *FmtText) ShowDetails() bool {
return f.Show&FormatShowDetails !=0 }
func (f *FmtText) ShowCause () bool {
return f.Show&FormatShowCause !=0 }
func (f *FmtText) ShowTrace () bool {
return f.Show&FormatShowTrace !=0 }
func (f *FmtText) ShowFieldEmpty () bool {
return f.Show&FormatShowFieldEmpty !=0 }
func FmtTextWithNameLenTransformer(len int) FmtTextFnc {
return func(f *FmtText) {
f.NameTransformers = append(f.NameTransformers,func(s string)string {
return astrings.Pad(s,len,' ',true)
})
}
}
func FmtTextWithNameTransformer (transformer ...astrings.Transform) FmtTextFnc {
return func(f *FmtText) {
f.NameTransformers = append(f.NameTransformers,transformer...)
}
}

@ -27,7 +27,7 @@ import "fmt"
const (
FormatColorBlack FormatColor = iota + 30
FormatColorBlack FmtTextColor = iota + 30
FormatColorRed
FormatColorGreen
FormatColorYellow
@ -40,21 +40,21 @@ const (
type (
FormatColor uint8
FmtTextColor uint8
)
func (c FormatColor) BeginColorString() string {
func (c FmtTextColor) BeginColorString() string {
return fmt.Sprintf("\u001B[%dm",uint8(c))
}
func (_ FormatColor) EndColorString () string {
func (_ FmtTextColor) EndColorString () string {
return "\x1b[0m" }
func (c FormatColor) Sprintf(fm string, params ...any) string {
func (c FmtTextColor) Sprintf(fm string, params ...any) string {
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", uint8(c),fmt.Sprintf(fm,params...)) }
func (c FormatColor) IsValid() bool {
func (c FmtTextColor) IsValid() bool {
return c >= FormatColorBlack && c <= FormatColorWhite }

@ -0,0 +1,204 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_text_builder.go
// Created by DEV
// Modified 30/03/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 errs
import (
"bytes"
"fmt"
"reflect"
"time"
)
type (
fmtTextState struct {
f *FmtText
buffer bytes.Buffer
level int
error error
}
)
func newFmtTextState(f *FmtText) *fmtTextState {
return &fmtTextState{ f : f } }
func (s *fmtTextState) Reset () {
s.buffer.Reset()
s.level = 0
s.error = nil
}
func (s *fmtTextState) Level () int {
return s.level }
func (s *fmtTextState) Error () error {
return s.error }
func (s *fmtTextState) Bytes () []byte {
return s.buffer.Bytes() }
func (s *fmtTextState) AddError (err error) {
if err == nil {
return
}
}
func (s *fmtTextState) AddCause (err error) {
if err == nil || !s.f.ShowCause() {
return
}
}
func (s *fmtTextState) AddTrace (trace StackTrace) {
if trace == nil || !s.f.ShowTrace() {
return
}
}
func (s *fmtTextState) AddWrapped(err error) {
if err == nil || !s.f.ShowWrapped() {
return
}
}
func (s *fmtTextState) AddCode (code string) {
s.writeField("error", s.f.ValueTransformers.Apply(code)) }
func (s *fmtTextState) AddType (ter string ) {
s.writeField("error-type",ter) }
func (s *fmtTextState) AddString (str string) {
s.writeString(s.f.StringTransformers.Apply(str))
}
func (s *fmtTextState) AddStrings(str []string) {
for _,st := range str {
s.writeString(s.f.StringTransformers.Apply(st))
}
}
func (s *fmtTextState) AddFieldString (name string, value string ) {
value = s.f.ValueTransformers.Apply(value)
if len(value) == 0 && !s.f.ShowFieldEmpty() {
return
}
s.writeField(name,value) }
func (s *fmtTextState) AddFieldInt (name string, value int ) {
s.writeField(name,fmt.Sprintf(s.f.IntLayout,value)) }
func (s *fmtTextState) AddFieldFloat (name string, value float64 ) {
s.writeField(name,fmt.Sprintf(s.f.FloatLayout,value)) }
func (s *fmtTextState) AddFieldTime (name string, value time.Time) {
s.writeField(name,value.Format(s.f.TimeLayout)) }
func (s *fmtTextState) AddFieldDate (name string, value time.Time) {
s.writeField(name,value.Format(s.f.DateLayout)) }
func (s *fmtTextState) writeField (name string, value string) {
name = s.f.NameTransformers.Apply (name)
if !s.f.ShowColors() {
s.writeString(name)
s.writeString(s.f.FieldSep)
s.writeString(value)
s.buffer.WriteString("\n")
}
}
func (s *fmtTextState) writeString(str string) {
s.buffer.WriteString(str)
}
func (s *fmtTextState) format (er error) {
dn := false
defer func(d *bool, s *fmtTextState){
if !(*d) {
if s.error == nil {
s.error = NewErrCause(G.ErrFormat,NewErrPanic(recover()))
} else {
s.error = NewErrCause(G.ErrFormat,s.error)
}
} else if s.level != 0 {
s.error = G.ErrFormatLevel
}
if s.error != nil {
panic(s.error)
}
}(&dn, s)
if fm,is := er.(Formattable); is {
fm.BuildFormat(s)
} else {
s.build(er)
}
dn=true
}
func (s *fmtTextState) build (er error) {
rt := reflect.TypeOf(er)
if rt.Kind() == reflect.Pointer {
er = reflect.ValueOf(er).Elem().Interface().(error)
if er == nil {
return
}
rt = rt.Elem()
}
s.AddCode(er.Error())
s.AddType(rt.String())
Extract(s,er)
s.AddWrapped(Unwrap(er))
s.AddCause (UnwrapCause(er))
s.AddTrace (UnwrapTrace(er))
}

@ -28,31 +28,30 @@ import "time"
type (
FormatBuilder interface {
Options() FormatOps
Reset ()
Level () int
Error () error
Bytes () []byte
AddError (err error, options ...FormatOpsFnc)
AddCause (err error, options ...FormatOpsFnc)
AddWrapped(err error, options ...FormatOpsFnc)
AddError (err error)
AddCause (err error)
AddWrapped(err error)
AddCode (code string, options ...FormatOpsFnc)
AddType (ter string , options ...FormatOpsFnc)
AddCode (code string)
AddType (ter string )
AddTrace (trace StackTrace, options ...FormatOpsFnc)
AddTrace (trace StackTrace)
AddString (str string, options ...FormatOpsFnc)
AddStrings (str []string, options ...FormatOpsFnc)
AddString (str string)
AddStrings (str []string)
AddFieldString (name string, value string , options ...FormatOpsFnc)
AddFieldInt (name string, value int , options ...FormatOpsFnc)
AddFieldFloat (name string, value float64 , options ...FormatOpsFnc)
AddFieldTime (name string, value time.Time, options ...FormatOpsFnc)
AddFieldString (name string, value string )
AddFieldInt (name string, value int )
AddFieldFloat (name string, value float64 )
AddFieldTime (name string, value time.Time)
AddFieldDate (name string, value time.Time)
}
)

@ -0,0 +1,103 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name field_extractor.go
// Created by DEV
// Modified 31/03/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 errs
import "time"
type (
FormatExtractor interface {
Extract (builder FormatBuilder, err error) bool
}
FormatExtractorFnc func (builder FormatBuilder, err error) bool
FormatExtractors []FormatExtractor
)
func (f FormatExtractorFnc) Extract (builder FormatBuilder, err error) bool {
return f(builder,err) }
func (l FormatExtractors) Extract (builder FormatBuilder, err error) bool {
if err == nil || len(l) == 0 {
return true
}
for _,f := range l {
if f != nil {
if !f.Extract(builder,err) {
return false
}
}
}
return true
}
func (l FormatExtractors) Append (exf ...FormatExtractor) FormatExtractors {
return append(l,exf...) }
func DefaultsExtractors () FormatExtractors {
return []FormatExtractor{
FormatExtractorFnc(func (b FormatBuilder, e error) bool {
if ms,is := e.(interface { Code() string }); is {
b.AddFieldString("code",ms.Code())
}
return true
}),
FormatExtractorFnc(func (b FormatBuilder, e error) bool {
if ms,is := e.(interface { Message() string }); is {
b.AddFieldString("message",ms.Message())
}
return true
}),
FormatExtractorFnc(func (b FormatBuilder, e error) bool {
if in,is := e.(interface { Info () string }); is {
b.AddFieldString("info",in.Info())
}
return true
}),
FormatExtractorFnc(func (b FormatBuilder, e error) bool {
if tm,is := e.(interface { Time() time.Time }); is {
b.AddFieldTime("time",tm.Time())
}
return true
}),
FormatExtractorFnc(func (b FormatBuilder, e error) bool {
if tm,is := e.(interface { Date() time.Time }); is {
b.AddFieldDate("date",tm.Date())
}
return true
}),
}
}

@ -1,83 +0,0 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name error_formattable_options.go
// Created by DEV
// Modified 30/03/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 errs
import (
"time"
"typex"
)
type (
FormatOps struct {
FormatShow
Indent string
FieldSep string
TimeLayout string
IntLayout string
FloatLayout string
Color FormatColor
CodeColor FormatColor
FieldNameColor FormatColor
FieldValueColor FormatColor
StringAdapters typex.StringAdapters
ValueAdapters typex.StringAdapters
NameAdapters typex.StringAdapters
}
FormatOpsFnc func (ops any)
)
func NewFormatOps (options ...FormatOpsFnc) *FormatOps {
os := &FormatOps {
Indent : " ",
FieldSep : " : ",
TimeLayout : time.RFC822Z,
IntLayout : "%d",
FloatLayout: "%-10s: %.2f",
}
for _,o := range options {
o(os)
}
return os
}
func (o *FormatOps) Clone (options ...FormatOpsFnc) *FormatOps {
if len(options) == 0 {
return o
}
no := *o
for _,op := range options {
op(&no)
}
return &no
}

@ -1,71 +0,0 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_use_ops.go
// Created by DEV
// Modified 30/03/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 errs
const (
FormatShowWrapped FormatShow = 1 << iota
FormatShowType
FormatShowColors
FormatShowIndent
FormatShowDetails
FormatShowCause
FormatShowTrace
FormatShowFieldEmpty
)
type (
FormatShow uint8
)
func (u FormatShow) ShowWrapped () bool {
return u&FormatShowWrapped !=0 }
func (u FormatShow) ShowType () bool {
return u&FormatShowType !=0 }
func (u FormatShow) ShowColors () bool {
return u&FormatShowColors !=0 }
func (u FormatShow) ShowIndent () bool {
return u&FormatShowIndent !=0 }
func (u FormatShow) ShowDetails() bool {
return u&FormatShowDetails !=0 }
func (u FormatShow) ShowCause () bool {
return u&FormatShowCause !=0 }
func (u FormatShow) ShowTrace () bool {
return u&FormatShowTrace !=0 }
func (u FormatShow) ShowFieldEmpty () bool {
return u&FormatShowFieldEmpty !=0 }

@ -1,84 +0,0 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_text_ops.go
// Created by DEV
// Modified 30/03/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 errs
import (
"time"
"typex"
)
type (
FormatTextOps struct {
FormatShow
Indent string
FieldSep string
TimeLayout string
IntLayout string
FloatLayout string
Color FormatColor
CodeColor FormatColor
FieldNameColor FormatColor
FieldValueColor FormatColor
StringAdapters typex.StringAdapters
ValueAdapters typex.StringAdapters
NameAdapters typex.StringAdapters
}
FormatTextOpsFnc func (ops *FormatTextOps)
)
func NewFormatTextOps (options ...FormatTextOpsFnc) *FormatTextOps {
os := &FormatTextOps {
Indent : " ",
FieldSep : " : ",
TimeLayout : time.RFC822Z,
IntLayout : "%d",
FloatLayout: "%-10s: %.2f",
}
for _,o := range options {
o(os)
}
return os
}
func (o *FormatTextOps) Clone (options ...FormatTextOpsFnc) *FormatTextOps {
if len(options) == 0 {
return o
}
no := *o
for _,op := range options {
op(&no)
}
return &no
}

@ -1,219 +0,0 @@
// ------------------------------------------------------------------------
// Project active2
// Active Thing (activething.com) git.activething.com/go
//
// File name format_text_builder.go
// Created by DEV
// Modified 30/03/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 errs
import (
"bytes"
"fmt"
"reflect"
"time"
)
type (
formatTextState struct {
options FormatTextOps
buffer bytes.Buffer
level int
error error
}
)
func newFormatTextState (options *FormatTextOps) *formatTextState {
st := &formatTextState{
options : *options,
}
return st
}
func (f *formatTextState) Options() FormatOps {
return f.options.FormatOps }
func (f *formatTextState) Reset () {
f.buffer.Reset()
f.level = 0
f.error = nil
}
func (f *formatTextState) Level () int {
return f.level }
func (f *formatTextState) Error () error {
return f.error }
func (f *formatTextState) Bytes () []byte {
return f.buffer.Bytes() }
func (f *formatTextState) AddError (err error, options ...FormatOpsFnc) {
if err == nil {
return
}
}
func (f *formatTextState) AddCause (err error, options ...FormatOpsFnc) {
if err == nil || !f.options.ShowCause() {
return
}
}
func (f *formatTextState) AddTrace (trace StackTrace, options ...FormatOpsFnc) {
if trace == nil || !f.options.ShowTrace() {
return
}
}
func (f *formatTextState) AddWrapped(err error, options ...FormatOpsFnc) {
if err == nil || !f.options.ShowWrapped() {
return
}
}
func (f *formatTextState) AddCode (code string, options ...FormatOpsFnc) {
f.writeField("error",f.options.ValueAdapters.Apply(code),options...) }
func (f *formatTextState) AddType (ter string , options ...FormatOpsFnc) {
f.writeField("error-type",ter, options ...) }
func (f *formatTextState) AddString (str string, options ...FormatOpsFnc) {
f.writeString(f.options.StringAdapters.Apply(str),options...)
}
func (f *formatTextState) AddStrings(str []string, options ...FormatOpsFnc) {
for _,s := range str {
f.writeString(f.options.StringAdapters.Apply(s))
}
}
func (f *formatTextState) AddFieldString (name string, value string , options ...FormatOpsFnc) {
value = f.options.ValueAdapters.Apply(value)
if len(value) == 0 && !f.options.ShowFieldEmpty() {
return
}
f.writeField(name,value) }
func (f *formatTextState) AddFieldInt (name string, value int , options ...FormatOpsFnc) {
f.writeField(name,fmt.Sprintf(f.options.IntLayout,value),options...) }
func (f *formatTextState) AddFieldFloat (name string, value float64 , options ...FormatOpsFnc) {
f.writeField(name,fmt.Sprintf(f.options.FloatLayout,value),options ...) }
func (f *formatTextState) AddFieldTime (name string, value time.Time, options ...FormatOpsFnc) {
f.writeField(name,value.Format(f.options.TimeLayout),options ...) }
func (f *formatTextState) writeField (name string, value string, options ...FormatOpsFnc) {
name = f.options.NameAdapters.Apply (name)
if !f.options.ShowColors() {
f.writeString(name)
f.writeString(f.options.FieldSep)
f.writeString(value)
f.buffer.WriteString("\n")
}
}
func (f *formatTextState) writeString(str string, options ...FormatOpsFnc) {
f.buffer.WriteString(str)
}
func (f *formatTextState) format (er error) {
dn := false
defer func(d *bool, s *formatTextState){
if !(*d) {
if s.error == nil {
s.error = NewErrCause(G.ErrFormat,NewErrPanic(recover()))
} else {
s.error = NewErrCause(G.ErrFormat,s.error)
}
} else if s.level != 0 {
s.error = G.ErrFormatLevel
}
}(&dn,f)
if fm,is := er.(Formattable); is {
fm.BuildFormat(f)
} else {
f.build(er)
}
dn=true
}
func (f *formatTextState) build (er error) {
rt := reflect.TypeOf(er)
if rt.Kind() == reflect.Pointer {
er = reflect.ValueOf(er).Elem().Interface().(error)
if er == nil {
return
}
rt = rt.Elem()
}
f.AddCode(er.Error())
f.AddType(rt.String())
if ms,is := er.(interface { Message() string }); is {
f.AddFieldString("message",ms.Message())
}
if in,is := er.(interface { Info () string }); is {
f.AddFieldString("info",in.Info())
}
if tm,is := er.(interface { Time() time.Time }); is {
f.AddFieldTime("time",tm.Time())
}
f.AddWrapped(Unwrap(er))
f.AddCause(UnwrapCause(er))
f.AddTrace(UnwrapTrace(er))
}

@ -29,7 +29,6 @@ import (
"strconv"
"sync"
"time"
"typex"
)
@ -268,13 +267,14 @@ func formatErrAny (s *FmtTextState, err error) {
}
func formatStackTrace(s *FmtTextState, t StackTrace) {
/*
for _,f := range t.Frames() {
s.WriteString(f.Package+"."+f.FuncName, FormatColorYellow)
s.WriteString(fmt.Sprintf(" %.90s:%d",f.File,f.LineNumber), FormatColorBlue)
if sc,er := f.SourceLine(); er == nil {
if len(sc) > 80 {
ls := typex.SplitString(sc,70)
//ls := typex.SplitString(sc,70)
for _,l := range ls {
s.Buffer.WriteString(FormatColorMagenta.BeginColorString())
s.Buffer.WriteString(" ")
@ -289,7 +289,7 @@ func formatStackTrace(s *FmtTextState, t StackTrace) {
s.Buffer.WriteByte('\n')
}
}
*/
}

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

@ -10,7 +10,7 @@ use (
./core/syncs
./core/timers
./core/ctxs
./core/typex
./core/atypes
./app

Loading…
Cancel
Save

Powered by TurnKey Linux.