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

master
DEV 2 years ago
parent 867a3cbd9b
commit c8c699b3b6

@ -2,6 +2,7 @@ package main
import (
"apack/pkjson"
"blds"
"errs"
"errs/eftext"
"fmt"
@ -11,7 +12,7 @@ import (
type (
S = struct {
S struct {
A string
}
)
@ -27,6 +28,11 @@ func randomInt(min, max int) int {
}
func (s S) Build (b blds.Builder) {
b.String("Esto es un campo S")
}
func main() {
@ -50,6 +56,7 @@ func main() {
"catorce": 15.16,
"dfate": time.Now(),
time.Now(): "ff",
"SSSS" : S{A:"a"},
}

@ -0,0 +1,53 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name active.go
// ✍️ Created by DEV
// 📅 Modified 28/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 "time"
type (
basicTypes interface {
~bool | ~string |
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
time.Time
}
)
var (
g = struct {
stringer keyStringer
}{
stringer: keyStringer{},
}
)

@ -0,0 +1,255 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name builder.go
// ✍️ Created by DEV
// 📅 Modified 28/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 (
"apack"
"apack/pstate"
"blds"
"cdcs/cjson"
)
type (
Builder struct {
*pstate.State
}
)
func (b *Builder) String (value string) {}
func (b *Builder) Bool (value bool) {}
func (b *Builder) writeString (value string, flags apack.Flags) {
if len(value) == 0 {
b.B.W(cjson.G.EmptyValue)
return
}
if flags.Encrypted() {
b.writeEncrypted([]byte(value),flags)
return
}
if flags.Binary() {
b.writeBinary([]byte(value),flags)
return
}
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)
return
}
rs := b.Encrypter.Encrypt(value)
if !rs.Ok() {
b.SetError(rs.Fail())
return
}
b.writeBinary(rs.Value(),flags)
}
func (b *Builder) writeBinary (value []byte, flags apack.Flags) {
if flags.Bin32() {
b.SetError(cjson.WriteBase32(b.B,value))
return
}
b.SetError(cjson.WriteBase64(b.B,value))
}
func (b *Builder) List (fnc func(builder blds.ListBuilder)) {
b.buildLevel(pstate.ModeList,fnc==nil,false,func(bl *Builder){
fnc(b) }) }
func (b *Builder) Map (fnc func(builder blds.MapBuilder)) {
b.buildLevel(pstate.ModeMap,fnc == nil, false, func(bl *Builder){
fnc(b) }) }
func (b *Builder) Object (fnc func(builder blds.ObjectBuilder)) {
b.buildLevel(pstate.ModeObject,fnc == nil, false, func(bl *Builder){
fnc(b) }) }
func (b *Builder) Item () blds.ValueBuilder {
if b.preElem() {
//nothing siempre es mode value
}
return b
}
func (b *Builder) Key (key any) blds.ValueBuilder {
if b.preElem() {
if key == nil {
b.SetError(apack.G.ErrInvalidKey.WithMessage("key is null"))
return b
}
g.stringer.packKey(b,key)
}
return b.postElem()
}
func (b *Builder) Field (name string) blds.ValueBuilder {
if len(name) == 0 {
b.SetError(apack.G.ErrInvalidKey.WithMessage("key is empty"))
return b
}
if b.preElem() {
b.writeString(name,apack.FlagScapeHTML)
}
return b.postElem()
}
func (b *Builder) buildLevel (mode pstate.Mode, isNil, isEmpty bool, buildFnc func(builder *Builder)) {
if !b.preValue() {
return
}
if isNil {
b.B.W(cjson.G.NullValue)
b.postValue()
return
}
if isEmpty {
if mode == pstate.ModeList {
b.B.Write2Byte('[',']')
} else {
b.B.Write2Byte('{','}')
}
b.postValue()
return
}
b.Open(mode)
be := byte('}')
if mode == pstate.ModeList {
b.B.WriteByte('[')
be = ']'
} else {
b.B.WriteByte('{')
}
buildFnc(b)
if b.Err != nil {
return
}
b.B.WriteByte(be)
b.Close(mode)
b.postValue()
}
func (b *Builder) preValue () bool {
if b.Err != nil {
panic(apack.G.ErrInvalidState.WithCause(b.Err))
}
if !b.Current.IsValue {
_ = b.SetError(apack.G.ErrStateInvalidElem)
return false
}
return true
}
func (b *Builder) postValue () {
if b.Err != nil {
return
}
b.Current.IsValue = false
b.Current.Count++
if b.Current.Mode == pstate.ModeValue {
b.Current.Mode = pstate.ModeNone
}
}
func (b *Builder) preElem () bool {
if b.Err != nil {
panic(apack.G.ErrInvalidState.WithCause(b.Err))
}
if b.Current.IsValue {
_ = b.SetError(apack.G.ErrStateInvalidElem)
return false
}
if b.Current.Count > 0 {
b.B.WriteByte(',')
}
return true
}
func (b *Builder) postElem () *Builder {
if b.Err == nil {
b.Current.IsValue = true
b.B.WriteByte(':')
}
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 packList [T basicTypes](b *Builder, list []T, flags apack.Flags, 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(',')
}
fncType(v)
if bl.Err != nil {
return
}
}
})
}

@ -0,0 +1,40 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name stringer.go
// ✍️ Created by DEV
// 📅 Modified 28/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
type (
keyStringer struct {}
)
func (s *keyStringer) packKey (b *Builder, value any) {}

@ -26,6 +26,7 @@ package pkjson
import (
"apack"
"blds"
"cdcs/cjson"
"encoding"
"encoding/json"
@ -60,19 +61,22 @@ var (
g = struct {
buildableType reflect.Type
stringifyType reflect.Type
jsonMarshalerType reflect.Type
textMarshalerType reflect.Type
keyStringer *keyStringer
keyStringer keyStringer
packersCache sync.Map
}{
stringifyType: reflect.TypeOf((*stringify)(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(),
keyStringer: defaultKeyStringer(),
keyStringer : *defaultKeyStringer(),
packersCache: *defaultPackers(),
}
)
@ -83,11 +87,18 @@ var (
func defaultPackers () *sync.Map {
mp := &sync.Map{}
mp.Store(reflect.TypeOf(time.Now()),func(b *Builder, v reflect.Value){
b.Time(v.Interface().(time.Time))
})
mp.Store(reflect.TypeOf(time.Duration(0)),func(b *Builder, v reflect.Value){
b.Duration(v.Interface().(time.Duration))
})
return mp
}
func defaultKeyStringer () *keyStringer {
return newKeyStringer(func(s *keyStringer){

@ -67,27 +67,21 @@ func (b *Builder) Pack (value any) []byte {
func (b *Builder) Any (value any) {
b.checkValue()
if value == nil {
b.checkValue()
_,_ = b.B.Write(cjson.G.NullValue)
b.postValue()
return
}
if bl,is := value.(blds.Buildable); is {
bl.Build(b)
b.postValue()
b.Buildable(bl)
return
}
if jm,is := value.(json.Marshaler); is {
dt,er := jm.MarshalJSON()
if er != nil {
b.SetError(er)
return
}
b.B.W(dt)
b.postValue()
b.Marshaller(jm)
return
}
@ -229,11 +223,38 @@ func (b *Builder) Time (value time.Time){
func (b *Builder) Duration(value time.Duration){
b.Int64(int64(value)) }
func (b *Builder) Reflect (value reflect.Value){
//todo reflect
}
func (b *Builder) Buildable(value blds.Buildable) {
b.checkValue()
if value == nil {
_,_ = b.B.Write(cjson.G.NullValue)
} else {
value.Build(b)
}
b.postValue()
}
func (b *Builder) Marshaller(value json.Marshaler) {
b.checkValue()
if value == nil {
_,_ = b.B.Write(cjson.G.NullValue)
} else {
dt, er := value.MarshalJSON()
if b.SetError(er) {
return
}
b.B.W(dt)
}
b.postValue()
}
func (b *Builder) List (fnc func (listBuilder blds.ListBuilder )){
@ -416,93 +437,3 @@ func (b *Builder) writeSepIf(cond bool) {
func packListString (p *Builder, list []string, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
p.packString(v, flags)
if p.Err != nil {
return
}
}
})
}
func packListError (p *Builder, list []error, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
if v == nil {
b.B.WOQ(true,'"',cjson.G.NullValue)
continue
}
p.packString(v.Error(), apack.FlagScapeHTML)
}
})
}
func packListBool (p *Builder, list []bool, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteBool(p.B,v)
}
})
}
func packListInt [T int | int8 | int16 | int32 | int64 | time.Duration](p *Builder, list []T, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteInt(p.B,int64(v))
}
})
}
func packListUInt [T uint | uint8 | uint16 | uint32 | uint64|uintptr](p *Builder, list []T, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteUint(p.B,uint64(v))
}
})
}
func packListFloat[T float32 | float64](p *Builder, list []T, flags apack.Flags, bits int) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteFloat(p.B,float64(v),bits)
}
})
}
func packListDate (p *Builder, list []time.Time, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteTime(p.B,v,flags.DateFormat())
}
})
}

@ -64,5 +64,3 @@ func (p Packer) Pack (value any) rsls.Bytes {

@ -0,0 +1,122 @@
// ------------------------------------------------------------------------
// 🚀 Project active3
// 🔗 Active Thing (activething.com) git.activething.com/go
//
// File name list_packer.go
// ✍️ Created by DEV
// 📅 Modified 28/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"
"time"
)
func packListString (p *Builder, list []string, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
p.packString(v, flags)
if p.Err != nil {
return
}
}
})
}
func packListError (p *Builder, list []error, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
if v == nil {
b.B.WOQ(true,'"',cjson.G.NullValue)
continue
}
p.packString(v.Error(), apack.FlagScapeHTML)
}
})
}
func packListBool (p *Builder, list []bool, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteBool(p.B,v)
}
})
}
func packListInt [T int | int8 | int16 | int32 | int64 | time.Duration](p *Builder, list []T, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteInt(p.B,int64(v))
}
})
}
func packListUInt [T uint | uint8 | uint16 | uint32 | uint64|uintptr](p *Builder, list []T, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteUint(p.B,uint64(v))
}
})
}
func packListFloat[T float32 | float64](p *Builder, list []T, flags apack.Flags, bits int) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteFloat(p.B,float64(v),bits)
}
})
}
func packListDate (p *Builder, list []time.Time, flags apack.Flags) {
p.makeLevel(pstate.ModeList,list == nil, len(list) == 0,func(b *Builder){
for i,v := range list {
if i > 0 {
p.B.WriteByte(sep)
}
cjson.WriteTime(p.B,v,flags.DateFormat())
}
})
}

@ -26,7 +26,9 @@ package pkjson
import (
"apack"
"blds"
"cdcs/cjson"
"encoding/json"
"reflect"
"sync"
)
@ -67,6 +69,20 @@ func packReflected(rtype reflect.Type) PackReflectedFnc {
func makePackReflectedFn(rtype reflect.Type) PackReflectedFnc {
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))
}
}
switch rtype.Kind() {
case reflect.Bool : return func(b *Builder, v reflect.Value) { b.Bool(v.Bool()) }

Loading…
Cancel
Save

Powered by TurnKey Linux.