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

master
DEV 2 years ago
parent 1637297250
commit b3e2a05590

@ -37,6 +37,17 @@ import (
type stringify interface{ String() string }
const (
jsonTag = "json"
maxCyclesAfter = 100
defaultFlags = apack.Flags(0)
)
const (
sep byte = ','
@ -56,93 +67,12 @@ var (
keyStringer *keyStringer
packersCache sync.Map
} {
stringifyType : reflect.TypeOf((*stringify)(nil)).Elem(),
}{
stringifyType: reflect.TypeOf((*stringify)(nil)).Elem(),
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
keyStringer : newKeyStringer(func(s *keyStringer){
// Registramos los tipos conocidos
fnI := func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatInt(k.Int(), 10)
return nil }
s.stringers[reflect.TypeOf(int (0))]=fnI
s.stringers[reflect.TypeOf(int8 (0))]=fnI
s.stringers[reflect.TypeOf(int16 (0))]=fnI
s.stringers[reflect.TypeOf(int32 (0))]=fnI
s.stringers[reflect.TypeOf(int64 (0))]=fnI
fnU := func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatUint(k.Uint(), 10)
return nil }
s.stringers[reflect.TypeOf(uint (0))]=fnU
s.stringers[reflect.TypeOf(uint8 (0))]=fnU
s.stringers[reflect.TypeOf(uint16 (0))]=fnU
s.stringers[reflect.TypeOf(uint32 (0))]=fnU
s.stringers[reflect.TypeOf(uint64 (0))]=fnU
s.stringers[reflect.TypeOf(uintptr(0))]=fnU
s.stringers[reflect.TypeOf(false)]= func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatBool(k.Bool())
return nil }
s.stringers[reflect.TypeOf(float64(0))]=func(e *rMapEntry, k reflect.Value) error {
e.k = cjson.JSONFloat(k.Float(),64)
return nil }
s.stringers[reflect.TypeOf(float32(0))]=func(e *rMapEntry, k reflect.Value) error {
e.k = cjson.JSONFloat(k.Float(), 32)
return nil }
s.stringers[reflect.TypeOf(time.Time{})]=func(e *rMapEntry, r reflect.Value) error {
e.k = (r.Interface().(time.Time)).String()
return nil }
s.stringers[reflect.TypeOf(time.Duration(0))]=func(e *rMapEntry, r reflect.Value) error {
e.k = strconv.FormatInt(r.Int(), 10)
return nil
}
// Registramos los ifaceCheckers conocido que pueden convertir su valor en clave
s.RegInterfaceChecker(
// Stringify Check
func(r reflect.Type) rMapEntryFnc {
if r.Implements(reflect.TypeOf((*stringify)(nil)).Elem()) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Kind() == reflect.Pointer && v.IsNil() {
return nil
}
e.k = (v.Interface().(stringify)).String()
e.f = apack.FlagScapeHTML
return nil
}
}
return nil
},
// Text Marshaller
func(r reflect.Type) rMapEntryFnc {
if r.Implements(reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Kind() == reflect.Pointer && v.IsNil() {
return nil
}
bf, er := v.Interface().(encoding.TextMarshaler).MarshalText()
if er != nil {
return er
}
e.k = string(bf)
e.f = apack.FlagScapeHTML
return nil
}
}
return nil
})
}),
keyStringer: defaultKeyStringer(),
}
)
@ -150,3 +80,90 @@ var (
func defaultKeyStringer () *keyStringer {
return newKeyStringer(func(s *keyStringer){
// Registramos los tipos conocidos
fnI := func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatInt(k.Int(), 10)
return nil }
s.stringers[reflect.TypeOf(int (0))]=fnI
s.stringers[reflect.TypeOf(int8 (0))]=fnI
s.stringers[reflect.TypeOf(int16 (0))]=fnI
s.stringers[reflect.TypeOf(int32 (0))]=fnI
s.stringers[reflect.TypeOf(int64 (0))]=fnI
fnU := func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatUint(k.Uint(), 10)
return nil }
s.stringers[reflect.TypeOf(uint (0))]=fnU
s.stringers[reflect.TypeOf(uint8 (0))]=fnU
s.stringers[reflect.TypeOf(uint16 (0))]=fnU
s.stringers[reflect.TypeOf(uint32 (0))]=fnU
s.stringers[reflect.TypeOf(uint64 (0))]=fnU
s.stringers[reflect.TypeOf(uintptr(0))]=fnU
s.stringers[reflect.TypeOf(false)]= func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatBool(k.Bool())
return nil }
s.stringers[reflect.TypeOf(float64(0))]=func(e *rMapEntry, k reflect.Value) error {
e.k = cjson.JSONFloat(k.Float(),64)
return nil }
s.stringers[reflect.TypeOf(float32(0))]=func(e *rMapEntry, k reflect.Value) error {
e.k = cjson.JSONFloat(k.Float(), 32)
return nil }
s.stringers[reflect.TypeOf(time.Time{})]=func(e *rMapEntry, r reflect.Value) error {
e.k = (r.Interface().(time.Time)).String()
return nil }
s.stringers[reflect.TypeOf(time.Duration(0))]=func(e *rMapEntry, r reflect.Value) error {
e.k = strconv.FormatInt(r.Int(), 10)
return nil
}
// Registramos los ifaceCheckers conocido que pueden convertir su valor en clave
s.RegInterfaceChecker(
// Stringify Check
func(r reflect.Type) rMapEntryFnc {
if r.Implements(reflect.TypeOf((*stringify)(nil)).Elem()) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Kind() == reflect.Pointer && v.IsNil() {
return nil
}
e.k = (v.Interface().(stringify)).String()
e.f = apack.FlagScapeHTML
return nil
}
}
return nil
},
// Text Marshaller
func(r reflect.Type) rMapEntryFnc {
if r.Implements(reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Kind() == reflect.Pointer && v.IsNil() {
return nil
}
bf, er := v.Interface().(encoding.TextMarshaler).MarshalText()
if er != nil {
return er
}
e.k = string(bf)
e.f = apack.FlagScapeHTML
return nil
}
}
return nil
})
})
}

@ -344,10 +344,6 @@ func (b *Builder) writeSepIf(cond bool) {
b.B.WriteByte(sep) } }
func (b *Builder) unsupportedType (rvalue reflect.Value) {
}

@ -125,46 +125,54 @@ func (s *keyStringer) getOrBuildStringer(rtype reflect.Type) rMapEntryFnc {
func (s *keyStringer) interfaceStringer(rtype reflect.Type) rMapEntryFnc {
return func(e *rMapEntry, k reflect.Value) error {
k = k.Elem()
if k.Type().Kind() == reflect.String {
e.k = k.String()
if rtype.Kind() == reflect.String {
return func(e *rMapEntry, v reflect.Value) error {
e.k = v.Elem().String()
e.f = apack.FlagScapeHTML
return nil
}
}
if t, h := k.Interface().(stringify); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
if rtype.Implements(g.stringifyType) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Elem().Type().Kind() == reflect.Pointer && v.Elem().IsNil() {
return nil
}
e.k = t.String()
e.k = (v.Interface().(stringify)).String()
e.f = apack.FlagScapeHTML
return nil
}
}
if t, h := k.Interface().(encoding.TextMarshaler); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
if rtype.Implements(g.textMarshalerType) {
return func(e *rMapEntry, v reflect.Value) error {
if v.Elem().Type().Kind() == reflect.Pointer && v.Elem().IsNil() {
return nil
}
bf, er := t.MarshalText()
bf, er := (v.Interface().(encoding.TextMarshaler)).MarshalText()
if er == nil {
e.k = string(bf)
e.f = apack.FlagScapeHTML
}
return er
}
}
return func(e *rMapEntry, v reflect.Value) error {
s.RLock()
fn := s.stringers[k.Type()]
fn := s.stringers[rtype]
s.RUnlock()
if fn != nil {
return fn(e,k)
return fn(e, v)
}
return apack.G.ErrInvalidKey
}
}

@ -222,7 +222,7 @@ func packReflected(rtype reflect.Type) func (b *Builder, v reflect.Value) {
return fi.(func(builder *Builder, value reflect.Value))
}
fn = makePackFn(rtype)
fn = makePackReflectedFn(rtype)
wg.Done()
g.packersCache.Store(rtype,fn)
@ -230,7 +230,7 @@ func packReflected(rtype reflect.Type) func (b *Builder, v reflect.Value) {
}
func makePackFn(rtype reflect.Type) func(b *Builder, v reflect.Value) {
func makePackReflectedFn(rtype reflect.Type) func(b *Builder, v reflect.Value) {
switch rtype.Kind() {
case reflect.Bool : return func(b *Builder, v reflect.Value) { b.Bool(v.Bool()) }
@ -253,10 +253,48 @@ func makePackFn(rtype reflect.Type) func(b *Builder, v reflect.Value) {
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 := packReflected(rtype.Elem())
return func(b *Builder, v reflect.Value) {
if v.IsNil() {
b.B.W(cjson.G.NullValue)
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() {
b.B.W(cjson.G.NullValue)
return
}
if v.Elem().IsNil() {
packReflectedInvalid(b,v.Elem())
return
}
packReflected(v.Elem().Type())(b,v.Elem())
}
default:
return func(b *Builder, v reflect.Value) {b.unsupportedType(v) }
return packReflectedInvalid
}
}
func packReflectedInvalid (b *Builder, _ reflect.Value) {
b.SetError(apack.G.ErrInvalidValue) }

@ -1,36 +0,0 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name reflect.go
// ✍️ Created by DEV
// 📅 Modified 11/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 pkjson
import "reflect"
func stringifyRKey (rtype reflect.Type) {
}
func buildKeyStringer (rtype reflect.Type) {
}

@ -0,0 +1,109 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name reflected_map.go
// ✍️ Created by DEV
// 📅 Modified 16/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 pkjson
import (
"apack"
"apack/pstate"
"cdcs/cjson"
"reflect"
"sort"
)
type (
rMap struct {
keyFn rMapEntryFnc
packFn func(builder *Builder, value reflect.Value)
}
)
func newRMap (rtype reflect.Type) *rMap {
return &rMap{
packFn: packReflected(rtype.Elem()),
keyFn : g.keyStringer.getOrBuildStringer(rtype.Key()),
}
}
func (m *rMap) pack (builder *Builder, value reflect.Value) {
if m.keyFn == nil {
builder.SetError(apack.G.ErrInvalidKey)
return
}
if value.IsNil() {
builder.B.W(cjson.G.NullValue)
return
}
if builder.Level > maxCyclesAfter {
if fn,ok := builder.CheckCycle(value.UnsafePointer()); ok {
defer fn()
} else {
builder.SetError(apack.G.ErrRedundantPack)
return
}
}
mi := value.MapRange()
ls := make(rMapEntries,value.Len())
for i:=0; mi.Next(); i++ {
ls[i]=rMapEntry{
v: mi.Value(),
}
if er := m.keyFn(&ls[i],mi.Key()); er != nil {
builder.SetError(er)
return
}
}
sort.Sort(ls)
builder.makeLevel(pstate.ModeMap,false,len(ls)==0,func (b *Builder){
for i:=0; i<len(ls); i++ {
if i > 0 {
b.B.WriteByte(',')
}
b.B.WriteString(ls[i].k)
b.B.WriteByte(':')
m.packFn(b,ls[i].v)
if b.Err != nil {
return
}
}
})
}
Loading…
Cancel
Save

Powered by TurnKey Linux.