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.

212 lines
6.2 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"
"reflect"
"sync"
"time"
)
var (
G = struct {
sentinel uint32
pool *sync.Pool
ErrInvalidNode errs.ErrCode
ErrInvalidElement errs.ErrCode
ErrInvalidKey errs.ErrCode
ErrDuplicatedKey errs.ErrCode
ErrKeyRequired errs.ErrCode
ErrValueRequired errs.ErrCode
ErrInvalidList errs.ErrCode
}{
ErrInvalidNode : errs.ErrCode("packs.invalid-Node"),
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"),
}
)
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))
}
}

Powered by TurnKey Linux.