|
|
|
@ -22,14 +22,15 @@
|
|
|
|
// limitations under the License.
|
|
|
|
// limitations under the License.
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
package pkj
|
|
|
|
package pkjson
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"apack"
|
|
|
|
"apacks"
|
|
|
|
"apack/pstate"
|
|
|
|
"apacks/pkstate"
|
|
|
|
"blds"
|
|
|
|
"blds"
|
|
|
|
"cdcs/cjson"
|
|
|
|
"cdcs/cjson"
|
|
|
|
"encoding/json"
|
|
|
|
"encoding/json"
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"reflect"
|
|
|
|
"rsls"
|
|
|
|
"rsls"
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
@ -38,28 +39,75 @@ import (
|
|
|
|
type (
|
|
|
|
type (
|
|
|
|
|
|
|
|
|
|
|
|
Builder struct {
|
|
|
|
Builder struct {
|
|
|
|
*pstate.State
|
|
|
|
*pkstate.State
|
|
|
|
e *json.Encoder
|
|
|
|
e *json.Encoder
|
|
|
|
f apack.Flags
|
|
|
|
f apack.Flags
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func NewBuilder () *Builder {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func NewBuilder(flag ...apack.Flags) *Builder {
|
|
|
|
|
|
|
|
f := apack.Flags(0)
|
|
|
|
|
|
|
|
if len(flag) == 1 {
|
|
|
|
|
|
|
|
f = flag[0]
|
|
|
|
|
|
|
|
} else if len(flag) > 1 {
|
|
|
|
|
|
|
|
for _,fl := range flag {
|
|
|
|
|
|
|
|
f|=fl
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return &Builder{
|
|
|
|
return &Builder{
|
|
|
|
State : pstate.AcquireState(),
|
|
|
|
State : pkstate.AcquireState(),
|
|
|
|
|
|
|
|
f : f,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) Pack (value any) rsls.Bytes {
|
|
|
|
func (b *Builder) release () {
|
|
|
|
|
|
|
|
pkstate.ReleaseState(b.State)
|
|
|
|
|
|
|
|
b.State = nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) Pack(value any) (rs rsls.Bytes) {
|
|
|
|
|
|
|
|
d := false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Defer function to handle panic recovery and resource release
|
|
|
|
|
|
|
|
defer func(bl *Builder, dn *bool){
|
|
|
|
|
|
|
|
// If not done, recover from any panic
|
|
|
|
|
|
|
|
if !(*dn) {
|
|
|
|
|
|
|
|
if rc := recover(); rc != nil {
|
|
|
|
|
|
|
|
if er, is := rc.(error); is {
|
|
|
|
|
|
|
|
rs = rsls.MakeBytesError(er)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
rs = rsls.MakeBytesError(fmt.Errorf("%#v", rc))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Release resources
|
|
|
|
|
|
|
|
bl.release()
|
|
|
|
|
|
|
|
}(b, &d)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Attempt to process the value
|
|
|
|
b.Any(value)
|
|
|
|
b.Any(value)
|
|
|
|
|
|
|
|
d = true // Mark as done if no panic occurred
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check for errors in the builder
|
|
|
|
if b.Err != nil {
|
|
|
|
if b.Err != nil {
|
|
|
|
return rsls.MakeBytesError(b.Err)
|
|
|
|
return rsls.MakeBytesError(b.Err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Return success result with bytes
|
|
|
|
return rsls.MakeBytesSuccess(b.B.Bytes())
|
|
|
|
return rsls.MakeBytesSuccess(b.B.Bytes())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) Any (value any) {
|
|
|
|
func (b *Builder) Any (value any) {
|
|
|
|
|
|
|
|
|
|
|
|
if value == nil {
|
|
|
|
if value == nil {
|
|
|
|
@ -153,7 +201,7 @@ func (b *Builder) Any (value any) {
|
|
|
|
case []time.Duration:
|
|
|
|
case []time.Duration:
|
|
|
|
packListG[time.Duration](b, v, b.Duration)
|
|
|
|
packListG[time.Duration](b, v, b.Duration)
|
|
|
|
case []error:
|
|
|
|
case []error:
|
|
|
|
b.buildLevel(pstate.ModeList, v == nil, len(v) == 0, func(bl *Builder) {
|
|
|
|
b.buildLevel(pkstate.ModeList, v == nil, len(v) == 0, func(bl *Builder) {
|
|
|
|
for _, e := range v {
|
|
|
|
for _, e := range v {
|
|
|
|
bl.Item()
|
|
|
|
bl.Item()
|
|
|
|
if bl.Err == nil {
|
|
|
|
if bl.Err == nil {
|
|
|
|
@ -196,7 +244,7 @@ func (b *Builder) Any (value any) {
|
|
|
|
case map[string]time.Duration:
|
|
|
|
case map[string]time.Duration:
|
|
|
|
packMapG[time.Duration](b, v, b.Duration)
|
|
|
|
packMapG[time.Duration](b, v, b.Duration)
|
|
|
|
case map[string]error:
|
|
|
|
case map[string]error:
|
|
|
|
b.buildLevel(pstate.ModeMap, v == nil, len(v) == 0, func(bl *Builder) {
|
|
|
|
b.buildLevel(pkstate.ModeMap, v == nil, len(v) == 0, func(bl *Builder) {
|
|
|
|
for k, v := range v {
|
|
|
|
for k, v := range v {
|
|
|
|
bl.Field(k)
|
|
|
|
bl.Field(k)
|
|
|
|
if bl.Err == nil {
|
|
|
|
if bl.Err == nil {
|
|
|
|
@ -386,17 +434,17 @@ func (b *Builder) writeBinary (value []byte, flags apack.Flags) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) List (fnc func(builder blds.ListBuilder)) {
|
|
|
|
func (b *Builder) List (fnc func(builder blds.ListBuilder)) {
|
|
|
|
b.buildLevel(pstate.ModeList,fnc==nil,false,func(bl *Builder){
|
|
|
|
b.buildLevel(pkstate.ModeList,fnc==nil,false,func(bl *Builder){
|
|
|
|
fnc(b) }) }
|
|
|
|
fnc(b) }) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) Map (fnc func(builder blds.MapBuilder)) {
|
|
|
|
func (b *Builder) Map (fnc func(builder blds.MapBuilder)) {
|
|
|
|
b.buildLevel(pstate.ModeMap,fnc == nil, false, func(bl *Builder){
|
|
|
|
b.buildLevel(pkstate.ModeMap,fnc == nil, false, func(bl *Builder){
|
|
|
|
fnc(b) }) }
|
|
|
|
fnc(b) }) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) Object (fnc func(builder blds.ObjectBuilder)) {
|
|
|
|
func (b *Builder) Object (fnc func(builder blds.ObjectBuilder)) {
|
|
|
|
b.buildLevel(pstate.ModeObject,fnc == nil, false, func(bl *Builder){
|
|
|
|
b.buildLevel(pkstate.ModeObject,fnc == nil, false, func(bl *Builder){
|
|
|
|
fnc(b) }) }
|
|
|
|
fnc(b) }) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -434,7 +482,7 @@ func (b *Builder) Field (name string) blds.ValueBuilder {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Builder) buildLevel (mode pstate.Mode, isNil, isEmpty bool, buildFnc func(builder *Builder)) {
|
|
|
|
func (b *Builder) buildLevel (mode pkstate.Mode, isNil, isEmpty bool, buildFnc func(builder *Builder)) {
|
|
|
|
if !b.preValue() {
|
|
|
|
if !b.preValue() {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -446,7 +494,7 @@ func (b *Builder) buildLevel (mode pstate.Mode, isNil, isEmpty bool, buildFnc fu
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if isEmpty {
|
|
|
|
if isEmpty {
|
|
|
|
if mode == pstate.ModeList {
|
|
|
|
if mode == pkstate.ModeList {
|
|
|
|
b.B.Write2Byte('[',']')
|
|
|
|
b.B.Write2Byte('[',']')
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
b.B.Write2Byte('{','}')
|
|
|
|
b.B.Write2Byte('{','}')
|
|
|
|
@ -457,7 +505,7 @@ func (b *Builder) buildLevel (mode pstate.Mode, isNil, isEmpty bool, buildFnc fu
|
|
|
|
|
|
|
|
|
|
|
|
b.Open(mode)
|
|
|
|
b.Open(mode)
|
|
|
|
be := byte('}')
|
|
|
|
be := byte('}')
|
|
|
|
if mode == pstate.ModeList {
|
|
|
|
if mode == pkstate.ModeList {
|
|
|
|
b.B.WriteByte('[')
|
|
|
|
b.B.WriteByte('[')
|
|
|
|
be = ']'
|
|
|
|
be = ']'
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -493,8 +541,8 @@ func (b *Builder) postValue () {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
b.Current.IsValue = false
|
|
|
|
b.Current.IsValue = false
|
|
|
|
b.Current.Count++
|
|
|
|
b.Current.Count++
|
|
|
|
if b.Current.Mode == pstate.ModeValue {
|
|
|
|
if b.Current.Mode == pkstate.ModeValue {
|
|
|
|
b.Current.Mode = pstate.ModeNone
|
|
|
|
b.Current.Mode = pkstate.ModeNone
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -533,7 +581,7 @@ func (b *Builder) encode (value any) error {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func packListG[T basicTypes](b *Builder, list []T, 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){
|
|
|
|
b.buildLevel(pkstate.ModeList,list == nil, len(list) == 0,func(bl *Builder){
|
|
|
|
for _,v := range list {
|
|
|
|
for _,v := range list {
|
|
|
|
b.Item()
|
|
|
|
b.Item()
|
|
|
|
if b.Err == nil {
|
|
|
|
if b.Err == nil {
|
|
|
|
@ -547,7 +595,7 @@ func packListG[T basicTypes](b *Builder, list []T, fncType func(vl T)) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func packMapG[T basicTypes](b *Builder, m map[string]T, fncType func(vl T)) {
|
|
|
|
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){
|
|
|
|
b.buildLevel(pkstate.ModeMap, m == nil, len(m) == 0, func(bl *Builder){
|
|
|
|
for k,v := range m {
|
|
|
|
for k,v := range m {
|
|
|
|
// Usamos b.Field y no b.Key porque sabemos que no es necesario
|
|
|
|
// 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
|
|
|
|
// hacerle un stringify y el objeto como el map la codificación
|