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

master
DEV 2 years ago
parent d938de815b
commit 78908f9087

@ -25,9 +25,12 @@
package pkjson
import (
"cdcs/cjson"
"encoding"
"encoding/json"
"reflect"
"strconv"
"time"
)
type stringify interface{ String() string }
@ -47,14 +50,67 @@ var (
jsonMarshalerType reflect.Type
textMarshalerType reflect.Type
kStringer *keyStringer
keyStringer *keyStringer
} {
stringifyType : reflect.TypeOf((*stringify)(nil)).Elem(),
jsonMarshalerType: reflect.TypeOf((*json.Marshaler)(nil)).Elem(),
textMarshalerType: reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem(),
kStringer: newKeyStringer(),
keyStringer : newKeyStringer(func(s *keyStringer){
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
}
}),
}
)
func RegKeyStringer (rtype reflect.Type, stringerFn rMapEntryFnc) {
g.keyStringer.Lock()
g.keyStringer.stringers[rtype]=stringerFn
g.keyStringer.Unlock()
}

@ -97,13 +97,20 @@ func (b *Builder) Key (key any) blds.ValueBuilder {
b.checkState()
b.writeSepIf(b.Items() > 0)
g.keyStringer.packStringifyKey(b,key)
b.IsValue = b.Err == nil
return b
}
func (b *Builder) Field (name string) blds.ValueBuilder {
b.checkState()
b.writeSepIf(b.Items() > 0)
b.IsValue = b.Err == nil
return b
}

@ -29,31 +29,29 @@ import (
"cdcs/cjson"
"encoding"
"reflect"
"strconv"
"sync"
"time"
)
type (
rMapEntry struct {
f apack.Flags // flags
v reflect.Value // value
k string // Key
}
rMapEntryFnc func(entry *rMapEntry, rkey reflect.Value) error
keyStringer struct {
sync.Mutex
sync.RWMutex
stringers map[reflect.Type]rMapEntryFnc
}
keyStringerFnc func (s *keyStringer)
)
func newKeyStringer () *keyStringer {
return &keyStringer{
func newKeyStringer (options...keyStringerFnc) *keyStringer {
s := &keyStringer{
stringers: make(map[reflect.Type]rMapEntryFnc),
}
for _,o := range options {
o(s)
}
return s
}
@ -79,7 +77,7 @@ func (s *keyStringer) packStringifyKey (b *Builder, key any) {
case time.Duration : cjson.WriteInt (b.B,int64(v),true)
default:
me := &rMapEntry{ v: reflect.ValueOf(key) }
fn := g.kStringer.getStringer(me.v.Type())
fn := g.keyStringer.getStringer(me.v.Type())
if fn == nil {
b.SetError(apack.G.ErrInvalidKey.WithMessage("cant convert key to string"))
return
@ -94,17 +92,23 @@ func (s *keyStringer) packStringifyKey (b *Builder, key any) {
func (s *keyStringer) getStringer (rtype reflect.Type) rMapEntryFnc {
s.Lock()
fn,hs := s.stringers[rtype]
if !hs {
fn = s.buildStringer(rtype)
s.stringers[rtype]=fn
s.RLock()
if fn,hs := s.stringers[rtype]; hs {
s.Unlock()
return fn
}
fn := s.buildStringer(rtype)
s.Lock()
s.stringers[rtype]=fn
s.Unlock()
return fn
}
func (s *keyStringer) buildStringer (rtype reflect.Type) rMapEntryFnc {
if rtype.Kind() == reflect.String {
@ -137,115 +141,12 @@ func (s *keyStringer) buildStringer (rtype reflect.Type) rMapEntryFnc {
}
}
switch rtype.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
return func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatInt(k.Int(), 10)
return nil
}
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
return func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatUint(k.Uint(), 10)
return nil
}
case reflect.Interface:
return func(e *rMapEntry, k reflect.Value) error {
k = k.Elem()
if k.Type().Kind() == reflect.String {
e.k = k.String()
e.f = apack.FlagScapeHTML
return nil
}
if t,h := k.Interface().(interface { String() string}); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
return nil
}
e.k = t.String()
e.f = apack.FlagScapeHTML
return nil
}
if t,h := k.Interface().(encoding.TextMarshaler); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
return nil
}
bf, er := t.MarshalText()
if er == nil {
e.k = string(bf)
e.f = apack.FlagScapeHTML
}
return er
}
switch rtype.Kind() {
case reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
e.k = strconv.FormatInt(k.Int(), 10)
return nil
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr:
e.k = strconv.FormatUint(k.Uint(), 10)
return nil
default:
return apack.G.ErrInvalidKey
}
}
default:
return nil
if rtype.Kind() == reflect.Interface {
return s.interfaceStringer(rtype)
}
}
return nil
func (s *keyStringer) buildStringerFn (rtype reflect.Type) rMapEntryFnc {
switch rtype.Kind() {
case reflect.String:
return func(e *rMapEntry, rkey reflect.Value) error {
e.k = rkey.String()
e.f = apack.FlagScapeHTML
return nil
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatInt(k.Int(), 10)
return nil
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return func(e *rMapEntry, k reflect.Value) error {
e.k = strconv.FormatUint(k.Uint(), 10)
return nil
}
case reflect.Interface:
return s.interfaceStringer(rtype)
default:
return nil
}
}
@ -259,7 +160,7 @@ func (s *keyStringer) interfaceStringer(rtype reflect.Type) rMapEntryFnc {
return nil
}
if t, h := k.Interface().(interface{ String() string }); h {
if t, h := k.Interface().(stringify); h {
if k.Type().Kind() == reflect.Pointer && k.IsNil() {
return nil
}
@ -280,15 +181,14 @@ func (s *keyStringer) interfaceStringer(rtype reflect.Type) rMapEntryFnc {
return er
}
switch rtype.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
e.k = strconv.FormatInt(k.Int(), 10)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
e.k = strconv.FormatUint(k.Uint(), 10)
return nil
default:
return apack.G.ErrInvalidKey
s.RLock()
fn := s.stringers[k.Type()]
s.RUnlock()
if fn != nil {
return fn(e,k)
}
return apack.G.ErrInvalidKey
}
}

@ -0,0 +1,48 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name r_map_entries.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
type (
rMapEntries []rMapEntry
)
func (e rMapEntries) Len() int {
return len(e)
}
func (e rMapEntries) Less(i, j int) bool {
return e[i].k < e[j].k
}
func (e rMapEntries) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}

@ -0,0 +1,45 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name rmap_entry.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 (
"apack"
"reflect"
)
type (
rMapEntry struct {
f apack.Flags // flags
v reflect.Value // value
k string // Key
}
rMapEntryFnc func(entry *rMapEntry, rkey reflect.Value) error
)

@ -23,7 +23,11 @@
package cjson
import "unicode/utf8"
import (
"math"
"strconv"
"unicode/utf8"
)
var (
@ -71,3 +75,36 @@ func initJSONChars() [utf8.RuneSelf]CharAtt {
}
return tb
}
func JSONFloat (f float64, bits int) string {
var t [64]byte
if math.IsInf(f, 0) || math.IsNaN(f) {
return string(G.FloatNaN)
}
abs := math.Abs(f)
fm := byte('f')
if abs != 0 {
if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
fm = 'e'
}
}
bf := t[:0]
bf = strconv.AppendFloat(bf, f, fm, -1, int(bits))
if fm == 'e' {
// clean up e-09 to e-9
n := len(bf)
if n >= 4 && bf[n-4] == 'e' && bf[n-3] == '-' && bf[n-2] == '0' {
bf[n-2] = bf[n-1]
bf = bf[:n-1]
}
}
return string(bf)
}

Loading…
Cancel
Save

Powered by TurnKey Linux.