From 3fca3ef79dc25d12fdedaac9a18bf4a84840aaf6 Mon Sep 17 00:00:00 2001 From: DEV Date: Tue, 20 Feb 2024 02:41:05 +0100 Subject: [PATCH] scopes --- app/main.go | 27 ++-- core/bins/bfields/bfield.go | 43 +++++- core/bins/bfields/bfields.go | 184 +++++++++++++++++++++++ core/bins/bfields/bfields_att.go | 53 +++++++ core/bins/bfields/bfields_ops.go | 37 +++++ core/bins/bfields/gogo.go | 16 +- core/bins/buffer.go | 3 +- core/bins/buffer_op.go | 9 ++ core/bins/buffer_pool_ops.go | 4 +- core/bins/buffer_writer_binary.go | 7 +- core/{ => bins}/chars/ascii_char_atts.go | 15 ++ core/{ => bins}/chars/char_att.go | 2 + core/{ => bins}/chars/char_atts.go | 0 core/{ => bins}/chars/gogo.go | 16 +- core/bins/gogo.go | 20 ++- core/chars/go.mod | 4 - core/errs/causer.go | 3 + core/errs/err_cause.go | 8 +- core/errs/err_code.go | 8 +- core/errs/err_group.go | 19 ++- core/errs/err_info.go | 28 ++++ core/errs/gogo.go | 14 +- core/errs/stack_print.go | 26 ++++ core/errs/stack_trace.go | 20 ++- core/errs/stack_trace_frame.go | 4 +- core/results/bytes.go | 41 +---- core/results/int.go | 3 + core/results/result.go | 20 ++- core/syncs/locker_read.go | 50 ++++++ core/syncs/locker_rw.go | 49 ++++++ core/syncs/locker_write.go | 50 ++++++ core/syncs/nop_locker.go | 45 ++++++ core/values/go.mod | 6 + core/values/gogo.go | 42 ++++++ core/values/properties.go | 118 +++++++++++++++ core/values/properties_att.go | 49 ++++++ core/values/scope.go | 133 ++++++++++++++++ core/values/scope_att.go | 43 ++++++ core/values/scope_ops.go | 58 +++++++ core/values/value_provider.go | 41 +++++ core/values/valuer.go | 75 +++++++++ go.work | 2 +- packs/fold.go | 2 +- packs/pjson/gogo.go | 2 +- packs/pjson/packer.go | 33 ++-- packs/pjson/packer_ops.go | 2 +- 46 files changed, 1307 insertions(+), 127 deletions(-) create mode 100644 core/bins/bfields/bfields.go create mode 100644 core/bins/bfields/bfields_att.go create mode 100644 core/bins/bfields/bfields_ops.go rename core/{ => bins}/chars/ascii_char_atts.go (96%) rename core/{ => bins}/chars/char_att.go (99%) rename core/{ => bins}/chars/char_atts.go (100%) rename core/{ => bins}/chars/gogo.go (85%) delete mode 100644 core/chars/go.mod create mode 100644 core/errs/stack_print.go create mode 100644 core/syncs/locker_read.go create mode 100644 core/syncs/locker_rw.go create mode 100644 core/syncs/locker_write.go create mode 100644 core/syncs/nop_locker.go create mode 100644 core/values/go.mod create mode 100644 core/values/gogo.go create mode 100644 core/values/properties.go create mode 100644 core/values/properties_att.go create mode 100644 core/values/scope.go create mode 100644 core/values/scope_att.go create mode 100644 core/values/scope_ops.go create mode 100644 core/values/value_provider.go create mode 100644 core/values/valuer.go diff --git a/app/main.go b/app/main.go index d741473..cfc485a 100644 --- a/app/main.go +++ b/app/main.go @@ -30,7 +30,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "encoding/base64" "fmt" "io" ) @@ -58,31 +57,28 @@ func (e encrypter) Encrypt (data []byte) results.Bytes { } st := cipher.NewCFBEncrypter(b,iv) st.XORKeyStream(ct[aes.BlockSize:],data) - return results.BytesSuccess(ct) + return results.DoBytesSuccess(ct) } func (e encrypter) Decrypt (data string) (string,error) { - cipherText, er := base64.StdEncoding.DecodeString(data) - if er != nil { - return "", fmt.Errorf("could not base64 decode: %v", er) - } + ct := []byte(data) block, err := aes.NewCipher(e.key) if err != nil { - return "", fmt.Errorf("could not create new cipher: %v", er) + return "", fmt.Errorf("could not create new cipher: %v", err) } - if len(cipherText) < aes.BlockSize { + if len(ct) < aes.BlockSize { return "", fmt.Errorf("invalid ciphertext block size") } - iv := cipherText[:aes.BlockSize] - cipherText = cipherText[aes.BlockSize:] + iv := ct[:aes.BlockSize] + ct = ct[aes.BlockSize:] stream := cipher.NewCFBDecrypter(block, iv) - stream.XORKeyStream(cipherText, cipherText) + stream.XORKeyStream(ct, ct) - return string(cipherText), nil + return string(ct), nil } @@ -90,7 +86,7 @@ func main() { en := encrypter{key: []byte{0,1,2,3,45,6,6,7,8,9,0,1,1,1,1,1}} - pk := pjson.NewPacker(pjson.PackerWithEncrypter(en)) + pk := pjson.NewPacker(pjson.WithEncrypter(en)) //pk := pjson.NewPacker() t := A { @@ -132,11 +128,10 @@ func main() { //errs.Test(pk.Cause(),true) fmt.Printf("Paquete %s\n",pk.Packet()) -/* res := en.Encrypt([]byte("Esto debe de ir encruptdao")) if res.IsError() { - panic(res.ErrorResult()) + panic(res.Cause()) } dt := string(res.Success()) fmt.Printf("seguro %s\n",dt) @@ -146,7 +141,7 @@ func main() { panic(er) } fmt.Printf("decrupt %s\n",st) -*/ + f,_ := bfields.NewBField([]byte("MiNombre"),[]byte("221100")) diff --git a/core/bins/bfields/bfield.go b/core/bins/bfields/bfield.go index 84338e5..bdb309a 100644 --- a/core/bins/bfields/bfield.go +++ b/core/bins/bfields/bfield.go @@ -23,6 +23,7 @@ package bfields +import "strconv" type ( @@ -58,11 +59,51 @@ func (f BField) String () string { r := make([]byte,len(f.name)+len(f.value)+1) copy(r,f.name) r[len(f.name)]=':' - copy(r[:len(f.name)+1],f.value) + copy(r[len(f.name)+1:],f.value) return string(r) } +func (f *BField) SetValue(val []byte) { + ln := len(val) + cp := cap(f.value) + if ln <= cp { + copy(f.value, val) + f.value = f.value[:ln] + return + } + nv := make([]byte, ln) + copy(f.value, nv) +} + + +func (f *BField) SetByte(val byte) { + f.value = append(f.value[:0], val) } + + +func (f *BField) SetBool(val bool) { + f.value = strconv.AppendBool(f.value[:0], val) } + + +func (f *BField) SetRune(val rune) { + f.value = strconv.AppendQuoteRune(f.value[:0], val) } + + +func (f *BField) SetString(val string) { + f.SetValue([]byte(val)) } + + + +func (f *BField) SetInt(val int64, bse int) { + f.value = strconv.AppendInt(f.value[:0], val, bse) } + + +func (f *BField) SetUInt(val uint64, bse int) { + f.value = strconv.AppendUint(f.value[:0], val, bse) } + + +func (f *BField) SetFloat(val float64, fmt byte, prc, sze int) { + f.value = strconv.AppendFloat(f.value[:0], val, fmt, prc, sze) } diff --git a/core/bins/bfields/bfields.go b/core/bins/bfields/bfields.go new file mode 100644 index 0000000..3dbaa1e --- /dev/null +++ b/core/bins/bfields/bfields.go @@ -0,0 +1,184 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bfield_list.go +// Created by DEV +// Modified 19/02/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 bfields + +import ( + "activething.com/go/gogo/core/opts" + "activething.com/go/gogo/core/slices" + "bytes" +) + +type ( + + BFields struct { + BFieldsAtt + fields []BField + } + + BFieldsWalkFnc func(index int, field *BField) bool +) + + + +func NewBFields (options ...opts.OptionErrFnc[BFields]) (*BFields,error) { + fs,er := opts.ApplyAndCheck(&BFields{},options...) + if er != nil { + return nil,er + } + if fs.IsReadOnly() { + + } + return fs,nil +} + + +func (f BFields) Get(nme []byte) *BField { + if ix := findField(f.fields, 0, nme); ix != slices.NotFound { + f.get(ix) + } + return nil +} + + +func (f BFields) get(index int) *BField { + if f.IsReadOnly() { + vl := f.fields[index] + return &vl + } + return &f.fields[index] +} + + +func (f *BFields) Add(nme, val []byte) error { + if f.IsFixed() { + return G.ErrFixed + } + if ix := findField(f.fields, 0, nme); ix != slices.NotFound { + if !f.IsMultiple() { + return G.ErrDuplicated + } + } + fl, er := NewBField(nme, val) + if er != nil { + return er + } + f.fields = append(f.fields, *fl) + return nil +} + +func (f *BFields) Del(nme []byte) error { + if f.IsFixed() { + return G.ErrFixed + } + if f.IsReadOnly() { + return G.ErrReadOnly + } + fm := 0 + ix := -1 + ln := len(f.fields) + for { + if ix = findField(f.fields, fm, nme); ix == slices.NotFound { + break + } + f.fields[ix] = f.fields[ln-1] + f.fields = f.fields[:ln-1] + ln -= 1 + if !f.IsMultiple() || ix == ln-1 { + break + } + fm = ix + } + return nil +} + +func (f *BFields) Upsert(nme, val []byte) error { + if len(nme) == 0 { + return nil + } + if f.IsReadOnly() { + return G.ErrReadOnly + } + if ix := findField(f.fields, 0, nme); ix != -1 { + f.fields[ix].SetValue(val) + return nil + } + if f.IsFixed() { + return G.ErrFixed + } + fl, er := NewBField(nme, val) + if er != nil { + return er + } + f.fields = append(f.fields, *fl) + return nil +} + + + +func (f BFields) Len() int { + return len(f.fields) } + + +func (f BFields) Has(nme []byte) bool { + return findField(f.fields, 0, nme) != slices.NotFound } + + +func (f BFields) Count(nme []byte) int { + rs := 0 + for _, fl := range f.fields { + if bytes.Equal(fl.name, nme) { + rs++ + } + } + return rs +} + + +func (f BFields) Walk(walker BFieldsWalkFnc) { + for ln, ix := len(f.fields), 0; ix < ln; ix++ { + if !walker(ix, f.get(ix)) { + return + } + } +} + + + +func findField(list []BField, from int, name []byte) int { + for ln, ix := len(list), from; ix < ln; ix++ { + if bytes.Equal(list[ix].name, name) { + return ix + } + } + return slices.NotFound +} + + + + + + + + + diff --git a/core/bins/bfields/bfields_att.go b/core/bins/bfields/bfields_att.go new file mode 100644 index 0000000..7f14120 --- /dev/null +++ b/core/bins/bfields/bfields_att.go @@ -0,0 +1,53 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bfields_att.go +// Created by DEV +// Modified 19/02/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 bfields + + +const( + + BFieldsAttReadOnly BFieldsAtt = 1 << iota + BFieldsAttFixed + BFieldsAttMultiple + +) + +type ( + + + BFieldsAtt uint8 + +) + + + +func (a BFieldsAtt) IsReadOnly() bool { + return a&BFieldsAttReadOnly != 0 } + + +func (a BFieldsAtt) IsFixed() bool { + return a&BFieldsAttFixed != 0 } + + +func (a BFieldsAtt) IsMultiple() bool { + return a&BFieldsAttMultiple != 0 } diff --git a/core/bins/bfields/bfields_ops.go b/core/bins/bfields/bfields_ops.go new file mode 100644 index 0000000..9f3752b --- /dev/null +++ b/core/bins/bfields/bfields_ops.go @@ -0,0 +1,37 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name bfields_ops.go +// Created by DEV +// Modified 19/02/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 bfields + +import "activething.com/go/gogo/core/opts" + +func WithField(nme, val []byte) opts.OptionErrFnc[BFields] { + return func(f *BFields) error { return f.Add(nme, val) }} + + +func WithAtts(atts BFieldsAtt) opts.OptionErrFnc[BFields] { + return func(f *BFields) error { + f.BFieldsAtt = atts + return nil + } +} diff --git a/core/bins/bfields/gogo.go b/core/bins/bfields/gogo.go index 413f38f..f418968 100644 --- a/core/bins/bfields/gogo.go +++ b/core/bins/bfields/gogo.go @@ -28,16 +28,16 @@ import "activething.com/go/gogo/core/errs" var ( G = struct { - ErrInvalidName errs.ErrCode - ErrBFieldDuplicated errs.ErrCode - ErrFixed errs.ErrCode - ErrReadOnly errs.ErrCode + ErrInvalidName errs.ErrCode + ErrDuplicated errs.ErrCode + ErrFixed errs.ErrCode + ErrReadOnly errs.ErrCode }{ - ErrInvalidName : errs.ErrCode("core:bins.bfields.invalid-name"), - ErrBFieldDuplicated : errs.ErrCode("core:bins.bfields.duplicated-field"), - ErrFixed : errs.ErrCode("core:bins.bfields.fixed"), - ErrReadOnly : errs.ErrCode("core:bins.bfields.read-only"), + ErrInvalidName: errs.ErrCode("core:bins.bfields.invalid-name"), + ErrDuplicated : errs.ErrCode("core:bins.bfields.duplicated-field"), + ErrFixed : errs.ErrCode("core:bins.bfields.fixed"), + ErrReadOnly : errs.ErrCode("core:bins.bfields.read-only"), } ) diff --git a/core/bins/buffer.go b/core/bins/buffer.go index 7c0ae3c..50cba41 100644 --- a/core/bins/buffer.go +++ b/core/bins/buffer.go @@ -24,8 +24,9 @@ package bins import ( + "activething.com/go/gogo/core/bins/chars" "bytes" - "chars" + "io" "unicode/utf8" ) diff --git a/core/bins/buffer_op.go b/core/bins/buffer_op.go index fcd49f6..b06057c 100644 --- a/core/bins/buffer_op.go +++ b/core/bins/buffer_op.go @@ -23,5 +23,14 @@ package bins +const ( + + opRead bufferOp = -1 // Any other read operation. + opInvalid bufferOp = 0 // Non-read operation. + opRune bufferOp = 1 // Decode rune of size 1. + +) + + type bufferOp int8 diff --git a/core/bins/buffer_pool_ops.go b/core/bins/buffer_pool_ops.go index d68b0a0..fb6de2a 100644 --- a/core/bins/buffer_pool_ops.go +++ b/core/bins/buffer_pool_ops.go @@ -28,14 +28,14 @@ import ( "sync/atomic" ) -func BufferPoolWithMaxPercentile(percentile float32) opts.OptionFnc[BufferPool] { +func WithMaxPercentile(percentile float32) opts.OptionFnc[BufferPool] { return func(b *BufferPool) { b.percentile = percentile } } -func BufferPoolWithCallsThreshold(threshold uint64) opts.OptionFnc[BufferPool] { +func CallsThreshold(threshold uint64) opts.OptionFnc[BufferPool] { return func(b *BufferPool) { atomic.StoreUint64(&b.threshold, threshold) } diff --git a/core/bins/buffer_writer_binary.go b/core/bins/buffer_writer_binary.go index 2571f5e..adc0d89 100644 --- a/core/bins/buffer_writer_binary.go +++ b/core/bins/buffer_writer_binary.go @@ -34,15 +34,14 @@ import ( func (b *Buffer) WriteBool(value bool) { if value { b.WriteByte(1) - } else { - b.WriteByte(0) + return } + b.WriteByte(0) } func (b *Buffer) WriteRune(value rune, byteOrder binary.ByteOrder) { - b.WriteUint32(uint32(value), byteOrder) -} + b.WriteUint32(uint32(value), byteOrder) } func (b *Buffer) WriteUint16(value uint16, byteOrder binary.ByteOrder) { diff --git a/core/chars/ascii_char_atts.go b/core/bins/chars/ascii_char_atts.go similarity index 96% rename from core/chars/ascii_char_atts.go rename to core/bins/chars/ascii_char_atts.go index 9c22332..8eefa14 100644 --- a/core/chars/ascii_char_atts.go +++ b/core/bins/chars/ascii_char_atts.go @@ -26,6 +26,21 @@ package chars +const ( + + ASCIIAttControl CharAtt = 1 << iota + ASCIIAttPrintable + ASCIIAttAlpha + + ASCIIAttAlphaLower + ASCIIAttAlphaUpper + ASCIIAttDigit + ASCIIAttHex + + ASCIIAttDigitHex = ASCIIAttHex | ASCIIAttDigit +) + + type ( diff --git a/core/chars/char_att.go b/core/bins/chars/char_att.go similarity index 99% rename from core/chars/char_att.go rename to core/bins/chars/char_att.go index 962e6df..c4edf88 100644 --- a/core/chars/char_att.go +++ b/core/bins/chars/char_att.go @@ -27,6 +27,8 @@ package chars + + type CharAtt uint8 diff --git a/core/chars/char_atts.go b/core/bins/chars/char_atts.go similarity index 100% rename from core/chars/char_atts.go rename to core/bins/chars/char_atts.go diff --git a/core/chars/gogo.go b/core/bins/chars/gogo.go similarity index 85% rename from core/chars/gogo.go rename to core/bins/chars/gogo.go index 0c286fe..5f9357e 100644 --- a/core/chars/gogo.go +++ b/core/bins/chars/gogo.go @@ -26,19 +26,7 @@ package chars -const ( - - ASCIIAttControl CharAtt = 1 << iota - ASCIIAttPrintable - ASCIIAttAlpha - ASCIIAttAlphaLower - ASCIIAttAlphaUpper - ASCIIAttDigit - ASCIIAttHex - - ASCIIAttDigitHex = ASCIIAttHex | ASCIIAttDigit -) const ( @@ -52,8 +40,8 @@ const ( var ( G = struct { - ASCII ASCIIAtts - HEX [16]byte + ASCII ASCIIAtts + HEX [16]byte }{ ASCII: *NewASCIIAtts(), HEX : [16]byte{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}, diff --git a/core/bins/gogo.go b/core/bins/gogo.go index 50d6476..046bc5c 100644 --- a/core/bins/gogo.go +++ b/core/bins/gogo.go @@ -26,13 +26,6 @@ package bins import "activething.com/go/gogo/core/errs" -const ( - - opRead bufferOp = -1 // Any other read operation. - opInvalid bufferOp = 0 // Non-read operation. - opRune bufferOp = 1 // Decode rune of size 1. - -) const ( @@ -56,6 +49,7 @@ var ( ErrNegativeRead errs.ErrCode ErrUnreadInvalid errs.ErrCode + bufferPool *BufferPool }{ ErrOutOfRange: errs.ErrCode("core:bins.out-of-range"), @@ -64,5 +58,17 @@ var ( ErrTooLarge: errs.ErrCode("core:bins.too-large"), ErrNegativeRead: errs.ErrCode("core:bins.negative-read"), ErrUnreadInvalid: errs.ErrCode("core:bins.unread-invalid"), + + bufferPool: NewBufferPool(), } ) + + + +func AcquireBuffer () *Buffer { + return G.bufferPool.Get() } + + +func ReleaseBuffer (buffer *Buffer) { + G.bufferPool.Put(buffer) } + diff --git a/core/chars/go.mod b/core/chars/go.mod deleted file mode 100644 index d0088d4..0000000 --- a/core/chars/go.mod +++ /dev/null @@ -1,4 +0,0 @@ -module chars - - -go 1.20 diff --git a/core/errs/causer.go b/core/errs/causer.go index 090259a..1a7030b 100644 --- a/core/errs/causer.go +++ b/core/errs/causer.go @@ -43,6 +43,9 @@ func (f CauserFnc) Cause() error { return f() } + + + /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/core/errs/err_cause.go b/core/errs/err_cause.go index 45c49a5..d20ae83 100644 --- a/core/errs/err_cause.go +++ b/core/errs/err_cause.go @@ -25,7 +25,10 @@ package errs -import "activething.com/go/gogo/core/opts" +import ( + "activething.com/go/gogo/core/opts" + "fmt" +) type ( @@ -66,6 +69,9 @@ func (e ErrCause) Unwrap() error { return e.cause } +func (e ErrCause) Error () string { + return fmt.Sprintf("Error (%s) \nCause (%s)\n)",e.error.Error(),e.cause.Error()) } + /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/core/errs/err_code.go b/core/errs/err_code.go index f3c658f..25db4ed 100644 --- a/core/errs/err_code.go +++ b/core/errs/err_code.go @@ -25,7 +25,10 @@ package errs -import "activething.com/go/gogo/core/opts" +import ( + "activething.com/go/gogo/core/opts" + "fmt" +) type ( @@ -46,7 +49,8 @@ type ( func (e ErrCode) Error() string { - return string(e) } + return fmt.Sprintf("Error (%s)\n)",e) } + func (e ErrCode) Stack() StackTrace { diff --git a/core/errs/err_group.go b/core/errs/err_group.go index 352c189..0fe9d3a 100644 --- a/core/errs/err_group.go +++ b/core/errs/err_group.go @@ -25,7 +25,11 @@ package errs -import "activething.com/go/gogo/core/opts" +import ( + "activething.com/go/gogo/core/opts" + "bytes" + "fmt" +) @@ -34,8 +38,17 @@ type ErrGroup ErrList -func (_ ErrGroup) Error() string { - return "core:errs.group-error" } +func (g ErrGroup) Error() (res string) { + bf := bytes.Buffer{} + defer bf.Reset() + + bf.WriteString("Error (core:errs.group-error) \n") + for i,e := range g { + bf.WriteString(fmt.Sprintf("Cause %d (%s)\n",i,e.Error())) + } + res = bf.String() + return +} func (g ErrGroup) Count() int { diff --git a/core/errs/err_info.go b/core/errs/err_info.go index b6a7a43..1779e39 100644 --- a/core/errs/err_info.go +++ b/core/errs/err_info.go @@ -27,6 +27,7 @@ package errs import ( "activething.com/go/gogo/core/opts" + "bytes" "time" ) @@ -101,6 +102,33 @@ func (i ErrInfo) Date() time.Time { return i.date } +func (i ErrInfo) Error () (res string) { + bf := bytes.Buffer{} + defer bf.Reset() + + bf.WriteString(i.error.Error()) + if len(i.message) > 0 { + bf.WriteString("\nmessage: ") + bf.WriteString(i.message) + } + if len(i.source) > 0 { + bf.WriteString("\nsource: ") + bf.WriteString(i.source) + } + //todo + //if !i.date.IsZero() { + // bf.WriteString("\nTime: ") + // bf.WriteTime(i.date) + //} + if i.stack != nil { + bf.WriteString("\nStack: ") + bf.WriteString(i.stack.String()) + } + res = bf.String() + + return res +} + /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/core/errs/gogo.go b/core/errs/gogo.go index 399382d..aec78ab 100644 --- a/core/errs/gogo.go +++ b/core/errs/gogo.go @@ -125,9 +125,21 @@ func getStackTrace(err error) StackTrace { } + +func String (err error) string { + if err == nil { + return "" + } + switch err.(type) { + default: + return err.Error() + } +} + + func Test(err error, halt bool) { if err != nil { - panic(err) + //panic(err) ei := NewErrInfo(err,ErrInfoWithStack()) if halt { panic(ei.Error()) diff --git a/core/errs/stack_print.go b/core/errs/stack_print.go new file mode 100644 index 0000000..b42648c --- /dev/null +++ b/core/errs/stack_print.go @@ -0,0 +1,26 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name stack_print.go +// Created by DEV +// Modified 19/02/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 + + diff --git a/core/errs/stack_trace.go b/core/errs/stack_trace.go index 92b40ab..8d7a9d1 100644 --- a/core/errs/stack_trace.go +++ b/core/errs/stack_trace.go @@ -25,7 +25,10 @@ package errs -import "runtime" +import ( + "bytes" + "runtime" +) @@ -56,6 +59,21 @@ func (s StackTrace) Frames() []StackTraceFrame { return st } + + +func (s StackTrace) String () (res string) { + bf := bytes.Buffer{} + defer bf.Reset() + + for _,f := range s { + bf.WriteString(StackTraceFrame(f).String()) + bf.WriteByte('\n') + } + res = bf.String() + return +} + + /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/core/errs/stack_trace_frame.go b/core/errs/stack_trace_frame.go index 9bf26f7..9573208 100644 --- a/core/errs/stack_trace_frame.go +++ b/core/errs/stack_trace_frame.go @@ -26,6 +26,7 @@ package errs import ( + "fmt" "path" "runtime" "strings" @@ -90,7 +91,8 @@ func (f StackTraceFrame) getFunc(cls bool) string { } - +func (f StackTraceFrame) String () string { + return fmt.Sprintf("%s:%d %s()\n", f.FileFull(), f.Line(), f.FuncName()) } /* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: diff --git a/core/results/bytes.go b/core/results/bytes.go index fe78757..1a2d58f 100644 --- a/core/results/bytes.go +++ b/core/results/bytes.go @@ -34,46 +34,15 @@ type ( Cause () error } - - BytesSuccess []byte - - BytesError struct { error } - - - ) -func (_ BytesSuccess) IsError () bool { - return false } - - -func (_ BytesSuccess) Cause () error { - return nil } - - -func (r BytesSuccess) Success () []byte { - return r } - - - - -func DoBytesError (err error) BytesError { - return BytesError { error: err } } - - -func (_ BytesError) IsError () bool { - return true } - - -func (r BytesError) Cause() error { - return r.error } - - -func (_ BytesError) Success () []byte { - return nil } - +func DoBytesSuccess (result []byte) Bytes { + return MakeSuccess[[]byte](result) +} +func DoBytesError (err error) Bytes { + return MakeError[[]byte](err) } diff --git a/core/results/int.go b/core/results/int.go index 6d2c8b5..7454f27 100644 --- a/core/results/int.go +++ b/core/results/int.go @@ -48,6 +48,9 @@ func (r IntSuccess) Success () int { return int(r) } +func DoIntError (err error) IntError { + return IntError { error: err } } + func (_ IntError) Success () int { return 0 } func (_ IntError) IsError () bool { return true } diff --git a/core/results/result.go b/core/results/result.go index 17dc0ee..eb29e8e 100644 --- a/core/results/result.go +++ b/core/results/result.go @@ -31,12 +31,12 @@ type ( Result[T any] interface { IsError () bool Success () T - Error () error + Cause () error } ResultSuccess[T any] struct { - data T + Result T } ResultError[T any] struct { error } @@ -44,18 +44,24 @@ type ( -func (_ ResultSuccess[T]) IsError () bool { - return false } +func MakeSuccess[T any] (res T) ResultSuccess[T] { + return ResultSuccess[T]{res} } + func (r ResultSuccess[T]) Success() T { - return r.data } + return r.Result } + +func (_ ResultSuccess[T]) IsError () bool { + return false } -func (_ ResultSuccess[T]) Error() error { +func (_ ResultSuccess[T]) Cause() error { return nil } +func MakeError[T any] (err error) ResultError[T] { + return ResultError[T] { error: err } } func (r ResultError[T]) Success() T { @@ -68,7 +74,7 @@ func (r ResultError[T]) IsError () bool { return true } -func (r ResultError[T]) Error () error { +func (r ResultError[T]) Cause () error { return r.error } diff --git a/core/syncs/locker_read.go b/core/syncs/locker_read.go new file mode 100644 index 0000000..1f09c00 --- /dev/null +++ b/core/syncs/locker_read.go @@ -0,0 +1,50 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// 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 syncs + +type ( + + + LockerRead interface { + RLock() + RUnlock() + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syncs/locker_rw.go b/core/syncs/locker_rw.go new file mode 100644 index 0000000..84e20fc --- /dev/null +++ b/core/syncs/locker_rw.go @@ -0,0 +1,49 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// 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 syncs + +type ( + + + LockerRW interface { + LockerRead + LockerWrite + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syncs/locker_write.go b/core/syncs/locker_write.go new file mode 100644 index 0000000..1c7fff0 --- /dev/null +++ b/core/syncs/locker_write.go @@ -0,0 +1,50 @@ +// +// Feb21 +// +// GO Active Thing +// Framework +// +// http://activething.com/dev/goat +// +// Dev : Juan V.Navarro +// Email: juanvnl@activething.com +// Date : 16/02/2021 +// +// Copyright 2021 the GOAT Authors +// +// 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 syncs + +type ( + + + LockerWrite interface { + Lock() + Unlock() + } +) + +/* + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + I HAVE NO DESIRE TO WALK ON WATER," SAID SIDDHARTA. + "LET THE OLD SHRAMANAS SATISFY THEMSELVES WITH SUCH SKILLS. + + SIDDHARTA + - HERMANN HESSE - + + ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +*/ diff --git a/core/syncs/nop_locker.go b/core/syncs/nop_locker.go new file mode 100644 index 0000000..7f1e368 --- /dev/null +++ b/core/syncs/nop_locker.go @@ -0,0 +1,45 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name nop_locker.go +// Created by DEV +// Modified 20/02/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 syncs + + +type ( + + LockerNop struct{} +) + + +func (_ LockerNop) Lock() {} + + +func (_ LockerNop) Unlock() {} + + +func (_ LockerNop) RLock() {} + + +func (_ LockerNop) RUnlock() {} + + + diff --git a/core/values/go.mod b/core/values/go.mod new file mode 100644 index 0000000..5c75c10 --- /dev/null +++ b/core/values/go.mod @@ -0,0 +1,6 @@ +module activething.com/go/gogo/values + + + +go 1.20 + diff --git a/core/values/gogo.go b/core/values/gogo.go new file mode 100644 index 0000000..11ab010 --- /dev/null +++ b/core/values/gogo.go @@ -0,0 +1,42 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name gogo.go +// Created by DEV +// Modified 20/02/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 values + +import "activething.com/go/gogo/core/errs" + +var ( + + G = struct { + + ErrInvalidScope errs.ErrCode + ErrInvalidScopeKey errs.ErrCode + ErrReadOnlyScope errs.ErrCode + + }{ + ErrInvalidScope: errs.ErrCode("core:values.invalid-scope"), + ErrInvalidScopeKey: errs.ErrCode("core:values.invalid-scope-key"), + ErrReadOnlyScope: errs.ErrCode("core:values.read-only-scope"), + } + +) \ No newline at end of file diff --git a/core/values/properties.go b/core/values/properties.go new file mode 100644 index 0000000..9ad6fac --- /dev/null +++ b/core/values/properties.go @@ -0,0 +1,118 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name properties.go +// Created by DEV +// Modified 20/02/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 values + +import "activething.com/go/gogo/core/opts" + +type ( + + Properties struct { + atts PropertiesAtt + parent *Properties + props map[string]any + } + + + PropertiesWalkFnc func(key string, value any) bool +) + + + + +func NewProperties (options ...opts.OptionFnc[Properties]) *Properties { + return opts.Apply(&Properties{ + props: make(map[string]any), + }, options ...) +} + + + + +func (p *Properties) Get (name string) (any,bool) { + v,h := p.props[name] + if h { + return v,true + } + if p.parent != nil { + return p.parent.Get(name) + } + return nil,false +} + + +func (p *Properties) Set (nme string, val interface{}) error { + if p.atts.IsReadOnly() { + return G.Errors.PropertiesReadOnly + } + if _,hs := p.props[nme]; !hs && p.IsFixed() { + return Errors.PropertiesFixed + } + p.props[nme]=val + return nil +} + + + +func (p *Properties) Del (nme string) error { + if p.ref != nil { + if _,hs := p.props[nme]; hs && p.IsReadOnly() { + return Errors.PropertiesReadOnly + } + delete(p.props,nme) + return nil + } + if _,hs := p.props[nme]; hs { + if p.IsFixed() { + return Errors.PropertiesFixed + } + if p.IsReadOnly() { + return Errors.PropertiesReadOnly + } + } + delete(p.props,nme) + return nil +} + + +// Properties.Map +// Desc: +// +// Prms: mfn, +// +func (p *Properties) Map (mfn PropertiesMapFnc) { + for ky,vl := range p.props { + if !mfn(ky,vl,false) { + return + } + } + if p.ref != nil { + for ky,vl := range p.ref.props { + if _,hs := p.props[ky]; !hs { + if !mfn(ky, vl, true) { + return + } + } + } + } +} diff --git a/core/values/properties_att.go b/core/values/properties_att.go new file mode 100644 index 0000000..4821e5c --- /dev/null +++ b/core/values/properties_att.go @@ -0,0 +1,49 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name properties_att.go +// Created by DEV +// Modified 20/02/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 values + + +const( + + PropertiesAttNone PropertiesAtt = 1 << iota + PropertiesAttFixed + PropertiesAttReadOnly +) + + + +type ( + + PropertiesAtt uint8 + +) + + +func (a PropertiesAtt) IsFixed () bool { + return a & PropertiesAttFixed != 0 } + + +func (a PropertiesAtt) IsReadOnly () bool { + return a & PropertiesAttReadOnly != 0 } + diff --git a/core/values/scope.go b/core/values/scope.go new file mode 100644 index 0000000..53e5ae2 --- /dev/null +++ b/core/values/scope.go @@ -0,0 +1,133 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name scope.go +// Created by DEV +// Modified 20/02/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 values + +import ( + "activething.com/go/gogo/core/opts" + "activething.com/go/gogo/core/syncs" +) + +type ( + + Scope struct { + locker syncs.LockerRW + atts ScopeAtt + parent ValueProvider + valuers map[any]Valuer + } + + ScopeWalkFnc func (key, value any) bool +) + + +func NewScope (options ...opts.OptionErrFnc[Scope]) (*Scope,error) { + return opts.ApplyAndCheck[Scope](&Scope { + valuers : make(map[any]Valuer), + }) +} + +func (s *Scope) Reset () { + s.locker.Lock() + s.parent = nil + for k,_ := range s.valuers { + delete(s.valuers,k) + } + s.locker.Unlock() +} + + +func (s *Scope) Attach (parent ValueProvider) { + s.locker.Lock() + s.parent = parent + s.locker.Unlock() +} + + +func (s *Scope) Detach() { + s.locker.Lock() + s.parent = nil + s.locker.Unlock() +} + + +func (s *Scope) Parent () ValueProvider { + s.locker.RLock() + p := s.parent + s.locker.RUnlock() + return p +} + + +func (s *Scope) Has (key any) bool { + s.locker.RLock() + _,h := s.valuers[key] + s.locker.RUnlock() + return h +} + +func (s *Scope) Value (key any) (any,bool) { + if key == nil { + return nil,false + } + s.locker.RLock() + v,h := s.valuers[key] + s.locker.RUnlock() + if h { + return v,true + } + if s.parent != nil { + return s.parent.Value(key) + } + return nil,false +} + +func (s *Scope) SetValue(key any, value any) error { + if key == nil { + return G.ErrInvalidScopeKey + } + s.locker.Lock() + if s.atts.IsReadOnly() { + s.locker.Unlock() + return G.ErrReadOnlyScope + } + s.valuers[key]= AsValuer(value) + s.locker.Unlock() + return nil +} + +func (s *Scope) DelValue (key any) { + s.locker.Lock() + delete (s.valuers,key) + s.locker.Unlock() +} + + + +func (s *Scope) Walk (walker ScopeWalkFnc) { + for k,v := range s.valuers { + if !walker(k,v.Value()) { + return + } + } +} diff --git a/core/values/scope_att.go b/core/values/scope_att.go new file mode 100644 index 0000000..b5c9915 --- /dev/null +++ b/core/values/scope_att.go @@ -0,0 +1,43 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name scope_att.go +// Created by DEV +// Modified 20/02/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 values + + + +const ( + + ScopeAttReadOnly ScopeAtt = 1 << iota +) + + + +type ( + + ScopeAtt uint8 +) + + +func (a ScopeAtt) IsReadOnly() bool { + return a&ScopeAttReadOnly != 0 } + diff --git a/core/values/scope_ops.go b/core/values/scope_ops.go new file mode 100644 index 0000000..4c9d08f --- /dev/null +++ b/core/values/scope_ops.go @@ -0,0 +1,58 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name scope_ops.go +// Created by DEV +// Modified 20/02/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 values + +import ( + "activething.com/go/gogo/core/opts" + "sync" +) + +func ScopeWithParent(parent ValueProvider) opts.OptionErrFnc[Scope] { + return func(sc *Scope) error { + sc.parent = parent + return nil + } +} + + +func ScopeWithLocker() opts.OptionErrFnc[Scope] { + return func(sc *Scope) error { + sc.locker = &sync.RWMutex{} + return nil + } +} + + +func ScopeWithValue(key, val interface{}) opts.OptionErrFnc[Scope] { + return func(sc *Scope) error { + return sc.SetValue(key, val) } +} + + +func ScopeWithReadOnly(att ScopeAtt) opts.OptionErrFnc[Scope] { + return func(sc *Scope) error { + sc.atts |= att + return nil + } +} \ No newline at end of file diff --git a/core/values/value_provider.go b/core/values/value_provider.go new file mode 100644 index 0000000..bc931db --- /dev/null +++ b/core/values/value_provider.go @@ -0,0 +1,41 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name value_provider.go +// Created by DEV +// Modified 20/02/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 values + + +type ( + + ValueProvider interface { + + Value (key any) (any,bool) + } + + ProviderValueFnc func(key any) (any,bool) +) + + + + +func (f ProviderValueFnc) Value (key any) (any,bool) { + return f(key) } diff --git a/core/values/valuer.go b/core/values/valuer.go new file mode 100644 index 0000000..91e087b --- /dev/null +++ b/core/values/valuer.go @@ -0,0 +1,75 @@ +// ------------------------------------------------------------------------ +// Project atila +// Active Thing (activething.com) git.activething.com/go +// +// File name valuer.go +// Created by DEV +// Modified 20/02/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 values + + + +type ( + + Valuer interface { + + Value () any + + } + + + ValueFnc func () any +) + + +func (f ValueFnc) Value() any { + return f() } + + + + +func AsValuer (value any) Valuer { + if value == nil { + return ValueFnc(nopValue) + } + switch tp := value.(type) { + case Valuer : return tp + case func() any : return ValueFnc(tp) + default: + return ValueFnc(func() any { return value }) + } +} + + + func AsValue (value any) any { + if value == nil { + return nil + } + if vl,is := value.(Valuer); is { + return vl.Value() + } + if vl,is := value.(func() any); is { + return vl() + } + return value + } + + +func nopValue () any { + return nil } \ No newline at end of file diff --git a/go.work b/go.work index f275962..906cecf 100644 --- a/go.work +++ b/go.work @@ -5,7 +5,6 @@ use ( ./app ./core - ./core/chars ./core/types ./core/bins ./core/errs @@ -14,6 +13,7 @@ use ( ./core/results ./core/times ./core/crypts + ./core/values ./packs ./sapis diff --git a/packs/fold.go b/packs/fold.go index 4fa2e40..6436966 100644 --- a/packs/fold.go +++ b/packs/fold.go @@ -24,8 +24,8 @@ package packs import ( + "activething.com/go/gogo/core/bins/chars" "bytes" - "chars" "unicode/utf8" ) diff --git a/packs/pjson/gogo.go b/packs/pjson/gogo.go index 08e9bde..675aa96 100644 --- a/packs/pjson/gogo.go +++ b/packs/pjson/gogo.go @@ -115,7 +115,7 @@ func Pack (value any, options ... opts.OptionFnc[Packer]) (res results.Bytes) { if p.Error() != nil { res = results.DoBytesError(p.Error()) } else { - res = results.BytesSuccess(p.Packet()) + res = results.DoBytesSuccess(p.Packet()) } p.Release() return res diff --git a/packs/pjson/packer.go b/packs/pjson/packer.go index 0c7a5dc..0282cf9 100644 --- a/packs/pjson/packer.go +++ b/packs/pjson/packer.go @@ -258,7 +258,7 @@ func packString (state *packs.State, value string , flags packs.Flags) { } if flags.Encrypted() { - packBinary(state, []byte(value), flags|packs.FlagBinary64) + packEncrypted(state, []byte(value), flags|packs.FlagBinary64) return } @@ -324,7 +324,24 @@ func packString (state *packs.State, value string , flags packs.Flags) { } +func packEncrypted (state *packs.State, value []byte, flags packs.Flags) { + r := state.Encrypter.Encrypt(value) + if r.IsError() { + state.SetError(r.Cause()) + return + } + state.WriteByte('"') + if flags.Bin64() || !flags.Binary() { + packBinary64(state, r.Success(), flags) + } else { + packBinary32(state, r.Success(), flags) + } + if state.Error == nil { + state.WriteByte('"') + } + return +} func packBinary (state *packs.State, value []byte , flags packs.Flags) { if state.Error != nil { @@ -341,22 +358,11 @@ func packBinary (state *packs.State, value []byte , flags packs.Flags) { } if flags.Encrypted() { - r := state.Encrypter.Encrypt(value) - if r.IsError() { - state.SetError(r.Cause()) - return - } - state.WriteByte('"') - packBinary64(state, r.Success(), flags) - if state.Error == nil { - state.WriteByte('"') - } + packEncrypted(state,value,flags) return } - state.WriteByte('"') - if flags.Bin64() { packBinary64(state, value, 0) } else if flags.Bin32() { @@ -365,7 +371,6 @@ func packBinary (state *packs.State, value []byte , flags packs.Flags) { state.SetError(packs.G.ErrUnsupportedType) return } - if state.Error == nil { state.WriteByte('"') } diff --git a/packs/pjson/packer_ops.go b/packs/pjson/packer_ops.go index fb26585..d48478e 100644 --- a/packs/pjson/packer_ops.go +++ b/packs/pjson/packer_ops.go @@ -31,7 +31,7 @@ import ( -func PackerWithEncrypter (encrypter crypts.Encrypter) opts.OptionFnc[Packer] { +func WithEncrypter(encrypter crypts.Encrypter) opts.OptionFnc[Packer] { return func(p *Packer) { if encrypter == nil { encrypter = crypts.EncrypterNop{}