You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
6.4 KiB
216 lines
6.4 KiB
// ------------------------------------------------------------------------
|
|
// Project atila
|
|
// Active Thing (activething.com) git.activething.com/go
|
|
//
|
|
// File name m.go
|
|
// Created by DEV
|
|
// Modified 16/01/2024
|
|
//
|
|
// Copyright 2024 activething.com
|
|
// ------------------------------------------------------------------------
|
|
// 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 __packs
|
|
|
|
import (
|
|
"activething.com/go/gogo/core/errs"
|
|
"activething.com/go/gogo/core/syncs"
|
|
"reflect"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
|
|
G = struct {
|
|
|
|
poolsSem uint32
|
|
statePool *syncs.Pool[State]
|
|
nodePool *syncs.Pool[StateNode]
|
|
|
|
ErrInvalidNode errs.ErrCode
|
|
ErrInvalidElement errs.ErrCode
|
|
ErrInvalidKey errs.ErrCode
|
|
ErrDuplicatedKey errs.ErrCode
|
|
ErrKeyRequired errs.ErrCode
|
|
ErrValueRequired errs.ErrCode
|
|
ErrInvalidList errs.ErrCode
|
|
ErrRedundantPack errs.ErrCode
|
|
}{
|
|
ErrInvalidNode : errs.ErrCode("packs.invalid-StateNode"),
|
|
ErrInvalidElement: errs.ErrCode("packs.invalid-element"),
|
|
ErrInvalidKey : errs.ErrCode("packs.invalid-key"),
|
|
ErrDuplicatedKey : errs.ErrCode("packs:duplicated-key"),
|
|
ErrKeyRequired : errs.ErrCode("packs:key-required"),
|
|
ErrValueRequired : errs.ErrCode("packs:value-required"),
|
|
ErrInvalidList : errs.ErrCode("packs:invalid-list"),
|
|
ErrRedundantPack : errs.ErrCode("packs:redundant-pack"),
|
|
}
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func BuildAny(builder Builder, value any, def func(value any) error) {
|
|
|
|
switch tp := value.(type) {
|
|
|
|
case Packabler: builder.SetError(tp.BuildPack(builder))
|
|
|
|
case error : builder.String(tp.Error())
|
|
|
|
case string : builder.String(tp)
|
|
case bool : builder.Bool (tp)
|
|
|
|
case int : builder.Int64(int64(tp))
|
|
case int8 : builder.Int8 (tp)
|
|
case int16 : builder.Int16(tp)
|
|
case int32 : builder.Int32(tp)
|
|
case int64 : builder.Int64(tp)
|
|
|
|
case uint : builder.UInt64(uint64(tp))
|
|
case uint8 : builder.UInt8 (tp)
|
|
case uint16 : builder.UInt16(tp)
|
|
case uint32 : builder.UInt32(tp)
|
|
case uint64 : builder.UInt64(tp)
|
|
|
|
case float32: builder.Float32(tp)
|
|
case float64: builder.Float64(tp)
|
|
|
|
case complex64 : builder.Complex64 (tp)
|
|
case complex128: builder.Complex128(tp)
|
|
|
|
case time.Time : builder.Date(tp)
|
|
case time.Duration: builder.Int64(int64(tp))
|
|
|
|
case reflect.Value:
|
|
switch tp.Kind() {
|
|
case reflect.Slice,
|
|
reflect.Array : packList (builder,value)
|
|
case reflect.Map : packMapReflected (builder,tp)
|
|
case reflect.Struct: packObjectReflected(builder,tp)
|
|
default:
|
|
builder.SetError(def(value))
|
|
}
|
|
|
|
default:
|
|
rf := reflect.ValueOf(value)
|
|
switch rf.Kind() {
|
|
case reflect.Slice,
|
|
reflect.Array : packList (builder,value)
|
|
case reflect.Map : packMapReflected (builder,rf)
|
|
case reflect.Struct: packObjectReflected(builder,rf)
|
|
}
|
|
BuildAny(builder,reflect.ValueOf(value),def)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func packListReflected(builder Builder, value reflect.Value) {
|
|
builder.List(func (p BuilderList) {
|
|
r := value
|
|
for i:=0; i<r.Len(); i++ {
|
|
p.ItemAny(r.Index(i).Interface())
|
|
if builder.Error() != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func packMapReflected(builder Builder, value reflect.Value) {
|
|
value.Type().Elem().Key().Kind()
|
|
builder.Map(func (p BuilderMap) {
|
|
r := value
|
|
for _,k := range r.MapKeys() {
|
|
p.ElemAny(k.Interface(),r.MapIndex(k).Interface())
|
|
if builder.Error() != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func packObjectReflected(builder Builder, value reflect.Value) {
|
|
builder.Object(func (p BuilderObject) {
|
|
r := value
|
|
t := r.Type()
|
|
for i:=0; i < r.NumField(); i++ {
|
|
if t.Field(i).IsExported() {
|
|
p.PropAny(t.Field(i).Name,r.Field(i).Interface())
|
|
if builder.Error() != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
func _packList[T any ] (builder Builder, values []T, call func(BuilderList,T)) {
|
|
builder.List(func (p BuilderList) {
|
|
for _,v := range values {
|
|
call(p,v)
|
|
if builder.Error() != nil {
|
|
return
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
func packList(builder Builder, value any) {
|
|
switch tp := value.(type) {
|
|
|
|
case []string : _packList[string](builder,tp, func (b BuilderList, v string) { b.ItemString(v) })
|
|
case []bool : _packList[bool ](builder,tp, func (b BuilderList, v bool ) { b.ItemBool (v) })
|
|
case []int8 : _packList[int8 ](builder,tp, func (b BuilderList, v int8 ) { b.ItemInt8 (v) })
|
|
case []int16 : _packList[int16 ](builder,tp, func (b BuilderList, v int16 ) { b.ItemInt16 (v) })
|
|
case []int32 : _packList[int32 ](builder,tp, func (b BuilderList, v int32 ) { b.ItemInt32 (v) })
|
|
case []int64 : _packList[int64 ](builder,tp, func (b BuilderList, v int64 ) { b.ItemInt64 (v) })
|
|
case []uint8 : _packList[uint8 ](builder,tp, func (b BuilderList, v uint8 ) { b.ItemUInt8 (v) })
|
|
case []uint16 : _packList[uint16](builder,tp, func (b BuilderList, v uint16) { b.ItemUInt16(v) })
|
|
case []uint32 : _packList[uint32](builder,tp, func (b BuilderList, v uint32) { b.ItemUInt32(v) })
|
|
case []uint64 : _packList[uint64](builder,tp, func (b BuilderList, v uint64) { b.ItemUInt64(v) })
|
|
|
|
case []float32 : _packList[float32](builder,tp, func (b BuilderList, v float32) { b.ItemFloat32(v) })
|
|
case []float64 : _packList[float64](builder,tp, func (b BuilderList, v float64) { b.ItemFloat64(v) })
|
|
|
|
case []complex64 : _packList[complex64] (builder,tp, func (b BuilderList, v complex64 ) { b.ItemComplex64 (v) })
|
|
case []complex128: _packList[complex128](builder,tp, func (b BuilderList, v complex128) { b.ItemComplex128(v) })
|
|
|
|
case []time.Time : _packList[time.Time] (builder,tp, func (b BuilderList, v time.Time) { b.ItemDate(v) })
|
|
|
|
case []time.Duration: _packList[time.Duration](builder,tp, func (b BuilderList, v time.Duration ) { b.ItemInt64 (int64(v)) })
|
|
|
|
case []any: _packList[any](builder,tp,func (b BuilderList, v any ) { b.ItemAny (v) })
|
|
|
|
case reflect.Value:
|
|
if tp.Type().Kind() != reflect.Slice && tp.Type().Kind() != reflect.Array {
|
|
builder.SetError(G.ErrInvalidList)
|
|
return
|
|
}
|
|
packListReflected(builder,tp)
|
|
default:
|
|
packListReflected(builder,reflect.ValueOf(value))
|
|
}
|
|
}
|
|
|
|
|