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

master
DEV 2 years ago
parent 5c35fe0555
commit 962bf90885

@ -64,6 +64,7 @@ var (
g = struct {
errorType reflect.Type
timeType reflect.Type
buildableType reflect.Type
stringifyType reflect.Type
jsonMarshalerType reflect.Type
@ -74,6 +75,7 @@ var (
}{
errorType : reflect.TypeOf((*error)(nil)).Elem(),
timeType : reflect.TypeOf(time.Time{}),
buildableType : reflect.TypeOf((*blds.Buildable)(nil)).Elem(),
stringifyType : reflect.TypeOf((*stringify)(nil)).Elem(),
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),

@ -26,11 +26,15 @@ package pkj
import (
"apack"
"apack/pstate"
"blds"
"cdcs/cjson"
"core/tups"
"encoding/json"
"reflect"
"sort"
"sync"
"time"
)
type (
@ -38,29 +42,183 @@ type (
rpackers struct {
mux sync.RWMutex
fncs map[reflect.Type]rPackFnc
ifcs []func(rtype reflect.Type) rPackFnc
}
rpackersFnc func(p *rpackers)
rPackFnc func(b *Builder, v reflect.Value)
)
func newRPackers () *rpackers {
return &rpackers{
fncs : make(map[reflect.Type]rPackFnc),
func newRPackers (options ...rpackersFnc) *rpackers {
ib := reflect.TypeOf((*blds.Buildable)(nil)).Elem()
ij := reflect.TypeOf((*json.Marshaler)(nil)).Elem()
ie := reflect.TypeOf((*error)(nil)).Elem()
ifcs := []func(rt reflect.Type) rPackFnc {
// Buildable
func(t reflect.Type) rPackFnc {
if t.Implements(ib) {
return func(b *Builder, v reflect.Value) {
b.Buildable(v.Interface().(blds.Buildable))
}
}
return nil
},
// jsonMarshaler
func(t reflect.Type) rPackFnc {
if t.Implements(ij) {
return func(b *Builder, v reflect.Value) {
b.Marshaller(v.Interface().(json.Marshaler))
}
}
return nil
},
// error
func(t reflect.Type) rPackFnc {
if t.Implements(ie) {
return func(b *Builder, v reflect.Value) {
b.Error(v.Interface().(error))
}
}
return nil
},
}
fncs := map[reflect.Type]rPackFnc {
reflect.TypeOf("") : func(b *Builder, v reflect.Value) { b.String(v.String())},
reflect.TypeOf(false) : func(b *Builder, v reflect.Value) { b.Bool (v.Bool())},
reflect.TypeOf(int (0)) : func(b *Builder, v reflect.Value) { b.Int64(v.Int()) },
reflect.TypeOf(int8 (0)) : func(b *Builder, v reflect.Value) { b.Int64(v.Int()) },
reflect.TypeOf(int16 (0)) : func(b *Builder, v reflect.Value) { b.Int64(v.Int()) },
reflect.TypeOf(int32 (0)) : func(b *Builder, v reflect.Value) { b.Int64(v.Int()) },
reflect.TypeOf(int64 (0)) : func(b *Builder, v reflect.Value) { b.Int64(v.Int()) },
reflect.TypeOf(uint (0)) : func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) },
reflect.TypeOf(uint8 (0)) : func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) },
reflect.TypeOf(uint16(0)) : func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) },
reflect.TypeOf(uint32(0)) : func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) },
reflect.TypeOf(uint64(0)) : func(b *Builder, v reflect.Value) { b.Uint64(v.Uint()) },
reflect.TypeOf(float32(0)) : func(b *Builder, v reflect.Value) { b.float(v.Float(),32)},
reflect.TypeOf(float64(0)) : func(b *Builder, v reflect.Value) { b.float(v.Float(),64)},
reflect.TypeOf(time.Time{}) : func(b *Builder, v reflect.Value) { b.Time(v.Interface().(time.Time)) },
reflect.TypeOf(time.Duration(0)): func(b *Builder, v reflect.Value) { b.Duration(v.Interface().(time.Duration))},
reflect.TypeOf([]string(nil)) : func(b *Builder, v reflect.Value) { packListG[string ] (b,v.Interface().([]string ), b.String)},
reflect.TypeOf([]bool (nil)) : func(b *Builder, v reflect.Value) { packListG[bool ] (b,v.Interface().([]bool ), b.Bool) },
reflect.TypeOf([]int (nil)) : func(b *Builder, v reflect.Value) { packListG[int ] (b,v.Interface().([]int ), b.Int) },
reflect.TypeOf([]int8 (nil)) : func(b *Builder, v reflect.Value) { packListG[int8 ] (b,v.Interface().([]int8 ), b.Int8) },
reflect.TypeOf([]int16 (nil)) : func(b *Builder, v reflect.Value) { packListG[int16 ] (b,v.Interface().([]int16 ), b.Int16) },
reflect.TypeOf([]int32 (nil)) : func(b *Builder, v reflect.Value) { packListG[int32 ] (b,v.Interface().([]int32 ), b.Int32) },
reflect.TypeOf([]int64 (nil)) : func(b *Builder, v reflect.Value) { packListG[int64 ] (b,v.Interface().([]int64 ), b.Int64) },
reflect.TypeOf([]uint (nil)) : func(b *Builder, v reflect.Value) { packListG[uint ] (b,v.Interface().([]uint ), b.Uint) },
reflect.TypeOf([]uint8 (nil)) : func(b *Builder, v reflect.Value) { packListG[uint8 ] (b,v.Interface().([]uint8 ), b.Uint8) },
reflect.TypeOf([]uint16(nil)) : func(b *Builder, v reflect.Value) { packListG[uint16 ] (b,v.Interface().([]uint16 ), b.Uint16)},
reflect.TypeOf([]uint32(nil)) : func(b *Builder, v reflect.Value) { packListG[uint32 ] (b,v.Interface().([]uint32 ), b.Uint32)},
reflect.TypeOf([]uint64(nil)) : func(b *Builder, v reflect.Value) { packListG[uint64 ] (b,v.Interface().([]uint64 ), b.Uint64)},
reflect.TypeOf([]uintptr(nil)): func(b *Builder, v reflect.Value) { packListG[uintptr] (b,v.Interface().([]uintptr), b.Uintptr)},
reflect.TypeOf([]float32(nil)): func(b *Builder, v reflect.Value) { packListG[float32] (b,v.Interface().([]float32), b.Float32)},
reflect.TypeOf([]float64(nil)): func(b *Builder, v reflect.Value) { packListG[float64] (b,v.Interface().([]float64), b.Float64)},
reflect.TypeOf([]time.Time (nil)): func(b *Builder, v reflect.Value) { packListG[time.Time ] (b,v.Interface().([]time.Time) , b.Time)},
reflect.TypeOf([]time.Duration(nil)): func(b *Builder, v reflect.Value) { packListG[time.Duration] (b,v.Interface().([]time.Duration), b.Duration)},
reflect.TypeOf([]error(nil)) : func(b *Builder, v reflect.Value) {
var l []error
if !v.IsNil() {
l = v.Interface().([]error)
}
b.buildLevel(pstate.ModeList, l == nil, len(l) == 0, func(bl *Builder) {
for _, e := range l {
bl.Item()
if bl.Err == nil {
bl.Error(e)
}
if bl.Err != nil {
return
}
}
})
},
reflect.TypeOf(map[string]string(nil)) : func(b *Builder, v reflect.Value) { packMapG[string ] (b,v.Interface().(map[string]string ), b.String)},
reflect.TypeOf(map[string]bool (nil)) : func(b *Builder, v reflect.Value) { packMapG[bool ] (b,v.Interface().(map[string]bool ), b.Bool) },
reflect.TypeOf(map[string]int (nil)) : func(b *Builder, v reflect.Value) { packMapG[int ] (b,v.Interface().(map[string]int ), b.Int) },
reflect.TypeOf(map[string]int8 (nil)) : func(b *Builder, v reflect.Value) { packMapG[int8 ] (b,v.Interface().(map[string]int8 ), b.Int8) },
reflect.TypeOf(map[string]int16 (nil)) : func(b *Builder, v reflect.Value) { packMapG[int16 ] (b,v.Interface().(map[string]int16 ), b.Int16) },
reflect.TypeOf(map[string]int32 (nil)) : func(b *Builder, v reflect.Value) { packMapG[int32 ] (b,v.Interface().(map[string]int32 ), b.Int32) },
reflect.TypeOf(map[string]int64 (nil)) : func(b *Builder, v reflect.Value) { packMapG[int64 ] (b,v.Interface().(map[string]int64 ), b.Int64) },
reflect.TypeOf(map[string]uint (nil)) : func(b *Builder, v reflect.Value) { packMapG[uint ] (b,v.Interface().(map[string]uint ), b.Uint) },
reflect.TypeOf(map[string]uint8 (nil)) : func(b *Builder, v reflect.Value) { packMapG[uint8 ] (b,v.Interface().(map[string]uint8 ), b.Uint8) },
reflect.TypeOf(map[string]uint16(nil)) : func(b *Builder, v reflect.Value) { packMapG[uint16 ] (b,v.Interface().(map[string]uint16 ), b.Uint16)},
reflect.TypeOf(map[string]uint32(nil)) : func(b *Builder, v reflect.Value) { packMapG[uint32 ] (b,v.Interface().(map[string]uint32 ), b.Uint32)},
reflect.TypeOf(map[string]uint64(nil)) : func(b *Builder, v reflect.Value) { packMapG[uint64 ] (b,v.Interface().(map[string]uint64 ), b.Uint64)},
reflect.TypeOf(map[string]uintptr(nil)): func(b *Builder, v reflect.Value) { packMapG[uintptr] (b,v.Interface().(map[string]uintptr), b.Uintptr)},
reflect.TypeOf(map[string]float32(nil)): func(b *Builder, v reflect.Value) { packMapG[float32] (b,v.Interface().(map[string]float32), b.Float32)},
reflect.TypeOf(map[string]float64(nil)): func(b *Builder, v reflect.Value) { packMapG[float64] (b,v.Interface().(map[string]float64), b.Float64)},
reflect.TypeOf(map[string]time.Time (nil)) : func(b *Builder, v reflect.Value) { packMapG[time.Time ] (b,v.Interface().(map[string]time.Time) , b.Time)},
reflect.TypeOf(map[string]time.Duration(nil)): func(b *Builder, v reflect.Value) { packMapG[time.Duration] (b,v.Interface().(map[string]time.Duration), b.Duration)},
reflect.TypeOf(map[string]error(nil)) : func(b *Builder, v reflect.Value) {
var l map[string]error
if !v.IsNil() {
l = v.Interface().(map[string]error)
}
b.buildLevel(pstate.ModeMap, l == nil, len(l) == 0, func(bl *Builder) {
for k,v := range l {
bl.Field(k)
if bl.Err == nil {
bl.Error(v)
}
if bl.Err != nil {
return
}
}
})
},
}
p := &rpackers{
fncs: fncs,
ifcs: ifcs,
}
for _,o := range options {
o(p)
}
return p
}
func (p *rpackers) getRPacker (rtype reflect.Type) rPackFnc {
p.mux.RLock()
fn, hs := p.fncs[rtype]
p.mux.RUnlock()
if hs {
p.mux.RUnlock()
return fn
}
for _,i := range p.ifcs {
if fn = i(rtype); fn != nil {
break
}
}
p.mux.RUnlock()
fn = p.buildRPacker(rtype)
if fn == nil {
fn = p.buildRPacker(rtype)
}
p.mux.Lock()
p.fncs[rtype]=fn
p.mux.Unlock()
@ -69,54 +227,12 @@ func (p *rpackers) getRPacker (rtype reflect.Type) rPackFnc {
}
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)) }
}
func (p *rpackers) buildRPacker (rtype reflect.Type) rPackFnc {
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) {
@ -157,9 +273,92 @@ func (p *rpackers) buildRPacker (rtype reflect.Type) rPackFnc {
case reflect.Slice,
reflect.Array :
eleFn := p.getRPacker(rtype.Elem())
return func(b *Builder, v reflect.Value) {
if v.IsNil() {
if b.preValue() {
b.B.W(cjson.G.NullValue)
}
b.postValue()
return
}
if b.Level > maxCyclesAfter {
c := struct {
p any
l int
}{
p: v.UnsafePointer(),
l: v.Len(),
}
if fn,ok := b.CheckCycle(c); ok {
defer fn()
} else {
b.SetError(apack.G.ErrRedundantPack)
return
}
}
b.buildLevel(pstate.ModeList, false, v.Len() == 0, func(bl *Builder){
for i:=0; i<v.Len();i++ {
bl.Item()
eleFn(bl,v.Index(i))
if bl.Err != nil {
return
}
}
})
}
case reflect.Map :
kfn := g.stringer.getStringer(rtype.Key())
if kfn == nil {
return func(b *Builder, _ reflect.Value) {
b.SetError(apack.G.ErrInvalidKey)
}
}
vfn := p.getRPacker(rtype.Elem())
return func(b *Builder, v reflect.Value) {
if b.Level > maxCyclesAfter {
if fn,ok := b.CheckCycle(v.UnsafePointer()); ok {
defer fn()
} else {
b.SetError(apack.G.ErrRedundantPack)
return
}
}
mi := v.MapRange()
ls := make([]tups.GTuple[string,reflect.Value],v.Len())
for i:=0; mi.Next(); i++ {
ls[i]=tups.GTuple[string,reflect.Value]{
A : kfn(mi.Key()),
B : mi.Value(),
}
}
sort.Slice(ls,func(i,j int) bool {
return ls[i].A < ls[j].A
})
b.buildLevel(pstate.ModeMap,v.IsNil(),v.Len() == 0,func(bl *Builder){
for i:=0; i<len(ls); i++ {
bl.Field(ls[i].A)
if b.Err == nil {
vfn(bl,ls[i].B)
}
if b.Err != nil {
return
}
}
})
}
case reflect.Struct :
return nil
default:

@ -24,19 +24,42 @@
package pkj
import (
"reflect"
"sync"
)
type (
stringers struct {
mux sync.RWMutex
fncs map[reflect.Type]stringerFnc
}
type (
stringersFnc func (s *stringers)
stringers struct {}
stringerFnc func (rvalue reflect.Value) string
)
func newStringers () *stringers {
return &stringers{}
func newStringers (options ...stringersFnc) *stringers {
fncs := map[reflect.Type]stringerFnc {
}
s := &stringers{ fncs : fncs }
for _,o := range options {
o(s)
}
return s
}
func (s *stringers) getStringer (rtype reflect.Type) stringerFnc {
return nil
}

Loading…
Cancel
Save

Powered by TurnKey Linux.