restructurando el codigo para actualizar los packs con la nueva arquitectura del builder

master
DEV 2 years ago
parent c8c699b3b6
commit 5da4029132

@ -1,10 +1,8 @@
package main
import (
"apack/pkjson"
"apack/pkj"
"blds"
"errs"
"errs/eftext"
"fmt"
"math/rand"
"time"
@ -37,7 +35,7 @@ func main() {
/*
p := pkjson.NewPacker()
@ -69,5 +67,17 @@ func main() {
}
fmt.Printf("Data\n\n%s",string(r.Value()))
*/
//l := []int {1,2,3,4}
//m := map[string]error {"1" : fmt.Errorf("un Error %s","ww"), "443" : fmt.Errorf("otro Error %s","des"),"UnoNulo":nil, "null":nil}
b := pkj.NewBuilder()
r := b.Pack(S{ A : "SOOOOOO"})
if !r.Ok() {
fmt.Printf("ERROR %s\n",r.Fail())
return
}
fmt.Printf("Data\n\n%s\n",string(r.Value()))
}

@ -24,11 +24,18 @@
package pkj
import "time"
import (
"apack"
"blds"
"encoding"
"encoding/json"
"reflect"
"time"
)
type (
basicTypes interface {
basicTypes interface {
~bool | ~string |
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
@ -36,17 +43,44 @@ type (
time.Time
}
stringify interface{ String() string }
)
const (
jsonTag = "json"
maxCyclesAfter = 100
defaultFlags = apack.Flags(0)
)
var (
g = struct {
stringer keyStringer
errorType reflect.Type
buildableType reflect.Type
stringifyType reflect.Type
jsonMarshalerType reflect.Type
textMarshalerType reflect.Type
rpackers *rpackers
stringer *stringers
}{
stringer: keyStringer{},
errorType : reflect.TypeOf((*error)(nil)).Elem(),
buildableType : reflect.TypeOf((*blds.Buildable)(nil)).Elem(),
stringifyType : reflect.TypeOf((*stringify)(nil)).Elem(),
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
stringer : newStringers(),
rpackers : newRPackers (),
}
)

@ -29,23 +29,322 @@ import (
"apack/pstate"
"blds"
"cdcs/cjson"
"encoding/json"
"reflect"
"rsls"
"time"
)
type (
Builder struct {
*pstate.State
e *json.Encoder
f apack.Flags
}
)
func NewBuilder () *Builder {
return &Builder{
State : pstate.AcquireState(),
}
}
)
func (b *Builder) Pack (value any) rsls.Bytes {
b.Any(value)
if b.Err != nil {
return rsls.MakeBytesError(b.Err)
}
return rsls.MakeBytesSuccess(b.B.Bytes())
}
func (b *Builder) Any (value any) {
if value == nil {
b.null()
return
}
if bl,is := value.(blds.Buildable); is {
b.Buildable(bl)
return
}
if ms,is := value.(json.Marshaler); is {
b.Marshaller(ms)
return
}
switch v := value.(type) {
case string:
b.String(v)
case int8:
b.Int64(int64(v))
case int16:
b.Int64(int64(v))
case int32:
b.Int64(int64(v))
case int64:
b.Int64(v)
case uint8:
b.Uint64(uint64(v))
case uint16:
b.Uint64(uint64(v))
case uint32:
b.Uint64(uint64(v))
case uintptr:
b.Uint64(uint64(v))
case uint64:
b.Uint64(v)
case float32:
b.float(float64(v), 32)
case float64:
b.float(v, 64)
case bool:
b.Bool(v)
case time.Time:
b.Time(v)
case time.Duration:
b.Int64(int64(v))
case error:
b.Error(v)
case []bool:
packListG[bool](b, v, b.Bool)
case []string:
packListG[string](b, v, b.String)
case []int:
packListG[int](b, v, b.Int)
case []int8:
packListG[int8](b, v, b.Int8)
case []int16:
packListG[int16](b, v, b.Int16)
case []int32:
packListG[int32](b, v, b.Int32)
case []int64:
packListG[int64](b, v, b.Int64)
case []uint:
packListG[uint](b, v, b.Uint)
case []uint8:
packListG[uint8](b, v, b.Uint8)
case []uint16:
packListG[uint16](b, v, b.Uint16)
case []uint32:
packListG[uint32](b, v, b.Uint32)
case []uint64:
packListG[uint64](b, v, b.Uint64)
case []uintptr:
packListG[uintptr](b, v, b.Uintptr)
case []time.Time:
packListG[time.Time](b, v, b.Time)
case []time.Duration:
packListG[time.Duration](b, v, b.Duration)
case []error:
b.buildLevel(pstate.ModeList, v == nil, len(v) == 0, func(bl *Builder) {
for _, e := range v {
bl.Item()
if bl.Err == nil {
bl.Error(e)
}
if bl.Err != nil {
return
}
}
})
case map[string]bool:
packMapG[bool](b, v, b.Bool)
case map[string]string:
packMapG[string](b, v, b.String)
case map[string]int:
packMapG[int](b, v, b.Int)
case map[string]int8:
packMapG[int8](b, v, b.Int8)
case map[string]int16:
packMapG[int16](b, v, b.Int16)
case map[string]int32:
packMapG[int32](b, v, b.Int32)
case map[string]int64:
packMapG[int64](b, v, b.Int64)
case map[string]uint:
packMapG[uint](b, v, b.Uint)
case map[string]uint8:
packMapG[uint8](b, v, b.Uint8)
case map[string]uint16:
packMapG[uint16](b, v, b.Uint16)
case map[string]uint32:
packMapG[uint32](b, v, b.Uint32)
case map[string]uint64:
packMapG[uint64](b, v, b.Uint64)
case map[string]uintptr:
packMapG[uintptr](b, v, b.Uintptr)
case map[string]time.Time:
packMapG[time.Time](b, v, b.Time)
case map[string]time.Duration:
packMapG[time.Duration](b, v, b.Duration)
case map[string]error:
b.buildLevel(pstate.ModeMap, v == nil, len(v) == 0, func(bl *Builder) {
for k, v := range v {
bl.Field(k)
if bl.Err == nil {
bl.Error(v)
}
if b.Err != nil {
return
}
}
})
case reflect.Value:
packReflected(v.Type())(b,v)
default:
rv := reflect.ValueOf(value)
packReflected(rv.Type())(b,rv)
}
}
func (b *Builder) Raw (value []byte) {
if !b.preValue() {
return
}
if value == nil {
b.B.W(cjson.G.NullValue)
} else if len(value) == 0 {
b.B.W(cjson.G.EmptyValue)
} else {
b.B.W(value)
}
b.postValue()
}
func (b *Builder) Binary(value []byte) {
if !b.preValue() {
return
}
b.writeBinary(value,b.f)
b.postValue()
}
func (b *Builder) String (value string) {}
func (b *Builder) String (value string) {
if !b.preValue() {
return
}
b.writeString(value,b.f)
b.postValue()
}
func (b *Builder) Bool (value bool) {}
func (b *Builder) Int (value int ){ b.Int64(int64(value)) }
func (b *Builder) Int8 (value int8 ){ b.Int64(int64(value)) }
func (b *Builder) Int16 (value int16 ){ b.Int64(int64(value)) }
func (b *Builder) Int32 (value int32 ){ b.Int64(int64(value)) }
func (b *Builder) Int64 (value int64 ){
if !b.preValue() {
return
}
cjson.WriteInt(b.B,value)
b.postValue()
}
func (b *Builder) Uint (value uint ){ b.Uint64(uint64(value)) }
func (b *Builder) Uint8 (value uint8 ){ b.Uint64(uint64(value)) }
func (b *Builder) Uint16 (value uint16 ){ b.Uint64(uint64(value)) }
func (b *Builder) Uint32 (value uint32 ){ b.Uint64(uint64(value)) }
func (b *Builder) Uintptr (value uintptr){ b.Uint64(uint64(value)) }
func (b *Builder) Uint64 (value uint64 ){
if !b.preValue() {
return
}
cjson.WriteUint(b.B,value)
b.postValue()
}
func (b *Builder) Float32 (value float32){
b.float(float64(value),32) }
func (b *Builder) Float64 (value float64){
b.float(value,64) }
func (b *Builder) float (value float64, bits int) {
if !b.preValue() {
return
}
cjson.WriteFloat(b.B,value,bits)
b.postValue()
}
func (b *Builder) Time (value time.Time) {
if !b.preValue() {
return
}
cjson.WriteTime(b.B,value,b.f.DateFormat())
b.postValue()
}
func (b *Builder) Duration (value time.Duration) { b.Int64(int64(value)) }
func (b *Builder) Error (value error) {
if !b.preValue() {
return
}
if value == nil {
b.B.W(cjson.G.NullValue)
} else {
b.writeString(value.Error(), b.f|apack.FlagScapeHTML)
}
b.postValue()
}
func (b *Builder) Buildable (value blds.Buildable) {
if !b.preValue() {
return
}
if value == nil {
} else {
value.Build(b)
}
b.postValue()
}
func (b *Builder) Marshaller (value json.Marshaler) {
if !b.preValue() {
return
}
if value == nil {
b.B.W(cjson.G.NullValue)
} else {
dt, er := value.MarshalJSON()
if b.SetError(er) {
return
}
b.B.W(dt)
}
b.postValue()
}
func (b *Builder) null () {
if !b.preValue() {
return
}
b.B.W(cjson.G.NullValue)
b.postValue()
}
func (b *Builder) writeString (value string, flags apack.Flags) {
if len(value) == 0 {
@ -63,7 +362,6 @@ func (b *Builder) writeString (value string, flags apack.Flags) {
cjson.WriteString(b.B,value,flags.EscapeHTML())
}
func (b *Builder) writeEncrypted(value []byte, flags apack.Flags) {
if b.Encrypter == nil {
b.SetError(apack.G.ErrInvalidEncrypter)
@ -105,7 +403,7 @@ func (b *Builder) Object (fnc func(builder blds.ObjectBuilder)) {
func (b *Builder) Item () blds.ValueBuilder {
if b.preElem() {
//nothing siempre es mode value
b.Current.IsValue = true
}
return b
}
@ -222,24 +520,23 @@ func (b *Builder) postElem () *Builder {
return b
}
func packAny (b *Builder, value any) {
switch tp := value.(type) {
case []bool : packList[bool ](b,tp,0,b.Bool)
case []string : packList[string](b,tp,0,b.String)
func (b *Builder) encode (value any) error {
if b.e == nil {
b.e = json.NewEncoder(b.B)
}
return b.e.Encode(value)
}
func packList [T basicTypes](b *Builder, list []T, flags apack.Flags, fncType func(vl T)) {
func packListG[T basicTypes](b *Builder, list []T, fncType func(vl T)) {
b.buildLevel(pstate.ModeList,list == nil, len(list) == 0,func(bl *Builder){
for i,v := range list {
if i > 0 {
bl.B.WriteByte(',')
for _,v := range list {
b.Item()
if b.Err == nil {
fncType(v)
}
fncType(v)
if bl.Err != nil {
return
}
@ -247,6 +544,24 @@ func packList [T basicTypes](b *Builder, list []T, flags apack.Flags, fncType fu
})
}
func packMapG[T basicTypes](b *Builder, m map[string]T, fncType func(vl T)) {
b.buildLevel(pstate.ModeMap, m == nil, len(m) == 0, func(bl *Builder){
for k,v := range m {
// Usamos b.Field y no b.Key porque sabemos que no es necesario
// hacerle un stringify y el objeto como el map la codificación
// json es la misma
b.Field(k)
if b.Err == nil {
fncType(v)
}
if b.Err != nil {
return
}
}
})
}

@ -0,0 +1,163 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name packer.go
// ✍️ Created by DEV
// 📅 Modified 30/05/2024
//
// 🔒 Copyright 2024 activething.com
//
// 📜 LICENSE --------------------------------------------------------------
// 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 pkj
import (
"blds"
"cdcs/cjson"
"encoding/json"
"reflect"
"sync"
)
type (
rpackers struct {
mux sync.RWMutex
fncs map[reflect.Type]rPackFnc
}
rPackFnc func(b *Builder, v reflect.Value)
)
func newRPackers () *rpackers {
return &rpackers{
fncs : make(map[reflect.Type]rPackFnc),
}
}
func (p *rpackers) getRPacker (rtype reflect.Type) rPackFnc {
p.mux.RLock()
fn, hs := p.fncs[rtype]
p.mux.RUnlock()
if hs {
return fn
}
fn = p.buildRPacker(rtype)
p.mux.Lock()
p.fncs[rtype]=fn
p.mux.Unlock()
return fn
}
func (p *rpackers) buildRPacker (rtype reflect.Type) rPackFnc {
if rtype.Implements(g.buildableType) {
return func(b *Builder, v reflect.Value) {
b.Buildable(v.Interface().(blds.Buildable))
}
}
if rtype.Implements(g.jsonMarshalerType) {
return func(b *Builder, v reflect.Value) {
b.Marshaller(v.Interface().(json.Marshaler))
}
}
if rtype.Implements(g.errorType) {
return func(b *Builder, v reflect.Value) {
b.Error(v.Interface().(error)) }
}
switch rtype.Kind() {
case reflect.Bool:
return func(b *Builder, v reflect.Value) { b.Bool(v.Bool()) }
case reflect.String:
return func(b *Builder, v reflect.Value) { b.String(v.String()) }
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
return func(b *Builder, v reflect.Value) { b.Int64(v.Int()) }
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
return func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) }
case reflect.Float32:
return func(b *Builder, v reflect.Value) { b.float(v.Float(), 32) }
case reflect.Float64:
return func(b *Builder, v reflect.Value) { b.float(v.Float(), 64) }
case reflect.Pointer:
eleFn := p.getRPacker(rtype.Elem())
return func(b *Builder, v reflect.Value) {
if v.IsNil() {
if !b.preValue() {
return
}
b.B.W(cjson.G.NullValue)
b.postValue()
return
}
b.Level++
if b.Level > maxCyclesAfter {
if fn,ok := b.CheckCycle(v.Interface()); ok {
defer fn()
} else {
return
}
}
eleFn(b,v.Elem())
b.Level--
}
case reflect.Interface:
return func(b *Builder, v reflect.Value) {
if v.IsNil() {
if !b.preValue() {
return
}
b.B.W(cjson.G.NullValue)
return
}
packReflected(v.Elem().Type())(b,v.Elem())
}
}
}

@ -2,7 +2,7 @@
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name stringer.go
// File name stringers.go
// ✍️ Created by DEV
// 📅 Modified 28/05/2024
//
@ -29,12 +29,16 @@ package pkj
type (
keyStringer struct {}
stringers struct {}
)
func newStringers () *stringers {
return &stringers{}
}
func (s *keyStringer) packKey (b *Builder, value any) {}
func (s *stringers) packKey (b *Builder, value any) {}

@ -25,7 +25,6 @@
package blds
import (
"reflect"
"time"
)
@ -37,7 +36,8 @@ type (
Any (value any)
Raw (value []byte)
Raw (value []byte)
Binary(value []byte)
String(value string)
@ -63,7 +63,6 @@ type (
Time (value time.Time )
Duration(value time.Duration)
Reflect (value reflect.Value)
List (buildFn func (b ListBuilder ))
Map (buildFn func (b MapBuilder ))

@ -27,7 +27,6 @@ package erdata
import (
"blds"
"flds"
"reflect"
"time"
)
@ -65,6 +64,8 @@ func (b *objectBuilder) add (field flds.Field) {
func (b *objectBuilder) Any (value any) { b.add (flds.NewFieldAny (b.curName,value)) }
func (b *objectBuilder) Raw (value []byte) { b.add (flds.NewFieldBinary (b.curName,value)) }
func (b *objectBuilder) Binary(value []byte) { b.add (flds.NewFieldBinary (b.curName,value)) }
func (b *objectBuilder) String(value string) { b.add (flds.NewFieldString (b.curName,value)) }
@ -91,7 +92,6 @@ func (b *objectBuilder) Error (value error) { b.add (flds.NewFieldError(b.curN
func (b *objectBuilder) Time (value time.Time) { b.add (flds.NewFieldTime (b.curName,value)) }
func (b *objectBuilder) Duration(value time.Duration) { b.add (flds.NewFieldDuration (b.curName,value)) }
func (b *objectBuilder) Reflect (value reflect.Value) { b.add (flds.NewFieldReflect (b.curName,value)) }
func (b *objectBuilder) List (_ func (_ blds.ListBuilder )) { b.add(nil) }
func (b *objectBuilder) Map (_ func (_ blds.MapBuilder )) { b.add(nil) }

@ -255,7 +255,7 @@ func (f GField[T]) BuildField (obuilder blds.ObjectBuilder) {
case KindTime : vb.Time (f.Value().(time.Time))
case KindDuration: vb.Duration(f.Value().(time.Duration))
case KindError : vb.Error (f.Value().(error))
case KindReflect : vb.Reflect (f.Value().(reflect.Value))
//case KindReflect : vb.Reflect (f.Value().(reflect.Value))
default:
vb.Any(f.Value())
}

Loading…
Cancel
Save

Powered by TurnKey Linux.