cdts creado, refinando ctype y cvalue

master
dev 1 year ago
parent 2b776dd35f
commit d6e5498605

@ -1,7 +1,9 @@
<component name="ProjectDictionaryState">
<dictionary name="project">
<words>
<w>ctype</w>
<w>cval</w>
<w>cvalue</w>
<w>ntype</w>
<w>vstate</w>
<w>vtype</w>

@ -0,0 +1,54 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 11/06/2025
// =============================================================================
package cdts
import (
"math"
"time"
)
var (
g = struct {
minTime,
maxTime time.Time
}{
minTime: time.Unix(0, math.MinInt64),
maxTime: time.Unix(0, math.MaxInt64),
}
E = struct {
InvalidCValueReflected,
InvalidCValueForType string
}{
InvalidCValueReflected : "::invalid_reflect_value",
InvalidCValueForType : "::invalid_value_for_type",
}
)

@ -0,0 +1,81 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
import "strings"
const (
CStateInvalid CState = 1 << iota // El valor almacenado es un valor invalido
CStateNil // Indica que el valor es nulo
CStateZero // Indica que el valor tiene valor 0
CStateReflected // Indica que el valor guardado es un value.reflect
CStateShort // Indica que el valor es la versión corta del valor, por ejemplo: los dates
CStateSensitive // Indica que el valor es delicado, por ejemplo no mostrar o no serializar
CStateEncoded // Indica que el valor está codificado
CStateError // Indica que el valor no ha podido ser establecido por un error que esta representado en el
// valor
CStateNone CState = 0
CStateOps CState = CStateEncoded|CStateSensitive
)
type CState uint8
func (s CState) HasInvalid () bool { return s&CStateInvalid != 0 }
func (s CState) HasNil () bool { return s&CStateNil != 0 }
func (s CState) HasZero () bool { return s&CStateZero != 0 }
func (s CState) HasReflected() bool { return s&CStateReflected != 0 }
func (s CState) HasShort () bool { return s&CStateShort != 0 }
func (s CState) HasSensitive() bool { return s&CStateSensitive != 0 }
func (s CState) HasEncoded () bool { return s&CStateEncoded != 0 }
func (s CState) HasError () bool { return s&CStateError != 0 }
func (s CState) HasNilOrZero() bool { return s&(CStateZero|CStateNil) != 0 }
func (s CState) setOption (options CState) CState { return s|(options&CStateOps) }
func (s CState) String() string {
states := [...]string{"invalid","nil","zero","reflected","short","sensitive","encoded","error"}
c := make([]string,0,4)
for i:=0; i<7; i++ {
if s& (1<<i) != 0 {
c=append(c,states[i])
}
}
if len(c) == 0 {
return ""
}
return strings.Join(c,":")
}

@ -0,0 +1,223 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
import "math/bits"
const (
CTypeInvalid CType = 0
// Tipos Bases
CTypeAny CType = 1 << 0
CTypeBool CType = 1 << 1
CTypeInt CType = 1 << 2
CTypeInt8 CType = 1 << 3
CTypeInt16 CType = 1 << 4
CTypeInt32 CType = 1 << 5
CTypeInt64 CType = 1 << 6
CTypeUint CType = 1 << 7
CTypeUint8 CType = 1 << 8
CTypeUint16 CType = 1 << 9
CTypeUint32 CType = 1 << 10
CTypeUint64 CType = 1 << 11
CTypeUintptr CType = 1 << 12
CTypeFloat32 CType = 1 << 13
CTypeFloat64 CType = 1 << 14
CTypeComplex64 CType = 1 << 15
CTypeComplex128 CType = 1 << 16
// CTypeDate time.Time
CTypeDate CType = 1 << 17
// CTypeDuration = time.Durations
CTypeDuration CType = 1 << 18
CTypeString CType = 1 << 19
CTypeBytes CType = 1 << 20
CTypeStack CType = 1 << 21
// Objetos
// CTypeCValue
// Es un valor compacto
CTypeCValue CType = 1 << 22
// Tipos base - Interfaces
CTypePackable CType = 1 << 23
CTypeContext CType = 1 << 24
CTypeError CType = 1 << 25
// CTypeNil Nulo Explícito
CTypeNil CType = 1 << 26
// CTypeObject, Structs, se le pone para determinar, este tipo siempre sera
// resultado de la reflexion del tipo ya que no se puede determinar si una
// variable es una struct o cualquier otro tipo
CTypeObject CType = 1 << 27
// Tipos compuestos
CTypeLazy CType = 1 << 28
CTypeList CType = 1 << 29
CTypeMap CType = 1 << 30
CTypeMapKey CType = 1 << 31
)
const (
// Mascaras de bits
maskCTypeComposite = CTypeList | CTypeMap | CTypePackable
maskCTypeBase = ^(maskCTypeComposite|CTypeMapKey)
maskCTypeInt = CTypeInt | CTypeInt8 | CTypeInt16 | CTypeInt32 | CTypeInt64
maskCTypeUint = CTypeUint | CTypeUint8 | CTypeUint16 | CTypeUint32 | CTypeUint64
maskCTypeNums = maskCTypeInt | maskCTypeUint
maskCTypeFloat = CTypeFloat32 | CTypeFloat64
maskCTypeComplex = CTypeComplex64 | CTypeComplex128
maskCTypeInterfaces = CTypePackable|CTypeError|CTypeContext
maskCTypeNullable= maskCTypeInterfaces | CTypeBytes | CTypeStack | CTypeString
)
const (
maxCTypes = 32
)
type CType uint32
func (t CType) IsComposite() bool { return t&maskCTypeComposite != 0 }
func (t CType) BaseType () CType {
if t&CTypeMap == 0 {
return t &maskCTypeBase
}
_,vt := t.MapType()
return vt
}
func (t CType) IsLazy () bool { return t&CTypeLazy != 0 }
func (t CType) IsList () bool { return t&CTypeList != 0 }
func (t CType) IsMap () bool { return t&CTypeMap != 0 }
func (t CType) MapType () (CType, CType) {
if t&CTypeMap == 0 {
return CTypeInvalid, CTypeInvalid
}
bs := t &maskCTypeBase
switch bits.OnesCount32(uint32(bs)) {
case 1: return bs,bs
case 2:
if t&CTypeMapKey == 0 {
return bs&-bs,bs&^(bs&-bs)
}
return bs&^(bs&-bs),bs&-bs
default:
return CTypeInvalid, CTypeInvalid
}
}
func (t CType) IsInvalid() bool { return t&maskCTypeBase == CTypeInvalid }
func (t CType) IsAny() bool { return t&maskCTypeBase == CTypeAny }
func (t CType) IsBool() bool { return t&maskCTypeBase == CTypeBool }
func (t CType) IsInt() bool { return t&maskCTypeBase == CTypeInt }
func (t CType) IsInt8() bool { return t&maskCTypeBase == CTypeInt8 }
func (t CType) IsInt16() bool { return t&maskCTypeBase == CTypeInt16 }
func (t CType) IsInt32() bool { return t&maskCTypeBase == CTypeInt32 }
func (t CType) IsInt64() bool { return t&maskCTypeBase == CTypeInt64 }
func (t CType) IsUint() bool { return t&maskCTypeBase == CTypeUint }
func (t CType) IsUint8() bool { return t&maskCTypeBase == CTypeUint8 }
func (t CType) IsUint16() bool { return t&maskCTypeBase == CTypeUint16 }
func (t CType) IsUint32() bool { return t&maskCTypeBase == CTypeUint32 }
func (t CType) IsUint64() bool { return t&maskCTypeBase == CTypeUint64 }
func (t CType) IsUintptr() bool { return t&maskCTypeBase == CTypeUintptr }
func (t CType) IsFloat32() bool { return t&maskCTypeBase == CTypeFloat32 }
func (t CType) IsFloat64() bool { return t&maskCTypeBase == CTypeFloat64 }
func (t CType) IsComplex64 () bool { return t&maskCTypeBase == CTypeComplex64 }
func (t CType) IsComplex128() bool { return t&maskCTypeBase == CTypeComplex128 }
func (t CType) IsDuration() bool { return t&maskCTypeBase == CTypeDuration }
func (t CType) IsDate() bool { return t&maskCTypeBase == CTypeDate }
func (t CType) IsString() bool { return t&maskCTypeBase == CTypeString }
func (t CType) IsBytes() bool { return t&maskCTypeBase == CTypeBytes }
func (t CType) IsStack() bool { return t&maskCTypeBase == CTypeStack }
func (t CType) IsCValue() bool { return t&maskCTypeBase == CTypeCValue }
func (t CType) IsPackable() bool { return t&maskCTypeBase == CTypePackable }
func (t CType) IsContext () bool { return t&maskCTypeBase == CTypeContext }
func (t CType) IsError() bool { return t&maskCTypeBase == CTypeError }
func (t CType) IsNil() bool { return t&maskCTypeBase == CTypeNil }
func (t CType) IsObject() bool { return t&maskCTypeBase == CTypeObject }
func setMapType(keyType, valType CType) CType {
if keyType == CTypeInvalid || valType == CTypeInvalid {
return CTypeInvalid
}
if keyType == valType {
return CTypeMap|keyType
}
if keyType < valType {
return CTypeMap|keyType|valType
}
return CTypeMap |valType|keyType| CTypeMapKey
}

@ -0,0 +1,103 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
const(
createByValue = iota
createByPtr
createByList
createByLazy
maxCValueCreators = 4
)
type (
cTypeInfo struct {
ctype CType
name string
creators [maxCValueCreators]func(any) CValue
}
cTypeInfoFnc func(info *cTypeInfo)
)
func createCTypeInfo [T any](cType CType, name string, createFnc func(value T) CValue, ops ...cTypeInfoFnc) cTypeInfo {
ti := cTypeInfo{
ctype : cType,
name : name,
creators: [maxCValueCreators]func(any) CValue{
/* createByValue */ func(v any) CValue { return createFnc(v.(T)) },
/* createByPtr */ func(v any) CValue {
value := v.(*T)
if value == nil {
return CValue{vType: cType, vState: CStateNil}
}
return createFnc(*value)
},
/* createByList */ func(v any) CValue {
tp := cType|CTypeList
vl := v.([]T)
ln := len(vl)
if ln == 0 {
if vl == nil {
return CValue{vType: tp, vState: CStateNil}
}
return CValue{vType: tp, vState: CStateZero}
}
return CValue{ vType: tp, intVal: int64(ln), anyVal: vl}
},
/* createByLazy */ func(v any) CValue {
tp := cType|CTypeLazy
vl := v.(func()T)
if vl == nil {
return CValue{ vType: tp, vState: CStateNil }
}
return CValue{ vType: tp, anyVal: vl}
},
},
}
for _,f := range ops {
f(&ti)
}
return ti
}

@ -0,0 +1,557 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
import (
"math/bits"
"reflect"
"sync"
)
type (
cTypeInfos struct {
mux sync.RWMutex
types [maxCTypes+1]cTypeInfo
cache map[reflect.Type]func(any)CValue
}
)
func newCTypeInfos() *cTypeInfos {
return &cTypeInfos{
mux : sync.RWMutex{},
cache: make(map[reflect.Type]func(value any)CValue),
types: [maxCTypes+1]cTypeInfo{
/* 0 */ createCTypeInfo[any ](CTypeInvalid,"invalid" ,createCValueInvalid,
func(i *cTypeInfo) {
i.creators[createByPtr] = createCValueInvalid
i.creators[createByList] = createCValueInvalid
i.creators[createByLazy] = createCValueInvalid
}),
/* 1 */createCTypeInfo [any ](CTypeAny ,"any" ,CreateCValueAny),
/* 2 */createCTypeInfo [bool ](CTypeBool ,"bool" ,CreateCValueBool),
/* 3 */createCTypeInfo [int ](CTypeInt ,"int" ,CreateCValueInt),
/* 4 */createCTypeInfo [int8 ](CTypeInt8 ,"int8" ,CreateCValueInt8),
/* 5 */createCTypeInfo [int16 ](CTypeInt16 ,"int16" ,CreateCValueInt16),
/* 6 */createCTypeInfo [int32 ](CTypeInt32 ,"int32" ,CreateCValueInt32),
/* 7 */createCTypeInfo [int64 ](CTypeInt64 ,"int64" ,CreateCValueInt64),
/* 8 */createCTypeInfo [uint ](CTypeUint ,"uint" ,CreateCValueUint),
/* 9 */createCTypeInfo [uint8 ](CTypeUint8 ,"uint8" ,CreateCValueUint8,
func(i *cTypeInfo) {
// El []uint8 debe de ser considerado como de tipo bytes
i.creators[createByList] = func(v any) CValue { return CreateCValueBytes(v.([]uint8)) }
}),
/* 10 */createCTypeInfo [uint16 ](CTypeUint16 ,"uint16" ,CreateCValueUint16),
/* 11 */createCTypeInfo [uint32 ](CTypeUint32 ,"uint32" ,CreateCValueUint32),
/* 12 */createCTypeInfo [uint64 ](CTypeUint64 ,"uint64" ,CreateCValueUint64),
/* 13 */createCTypeInfo [uintptr ](CTypeUintptr ,"uintptr" ,CreateCValueUintptr),
/* 14 */createCTypeInfo [float32 ](CTypeFloat32 ,"float32" ,CreateCValueFloat32),
/* 15 */createCTypeInfo [float64 ](CTypeFloat64 ,"float64" ,CreateCValueFloat64),
/* 16 */createCTypeInfo [complex64 ](CTypeComplex64,"complex64" ,CreateCValueComplex64),
/* 17 */createCTypeInfo [complex128 ](CTypeComplex128,"complex128" ,CreateCValueComplex128),
/* 18 */createCTypeInfo [Date ](CTypeDate ,"date" ,CreateCValueDate),
/* 19 */createCTypeInfo [Duration ](CTypeDuration ,"duration" ,CreateCValueDuration),
/* 20 */createCTypeInfo [string ](CTypeString ,"string" ,CreateCValueString),
/* 21 */createCTypeInfo [Bytes ](CTypeBytes ,"bytes" ,CreateCValueBytes),
/* 22 */createCTypeInfo [Stack ](CTypeStack ,"stack" ,CreateCValueStack),
/* 23 */createCTypeInfo [CValue ](CTypeCValue ,"cvalue" ,createCValueCValue),
/* 24 */createCTypeInfo [Packable ](CTypePackable ,"packable" ,CreateCValuePackable),
/* 25 */createCTypeInfo [Context ](CTypeContext ,"context" ,CreateCValueContext),
/* 26 */createCTypeInfo [error ](CTypeError ,"error" ,CreateCValueError),
/* 27 */createCTypeInfo [any ](CTypeNil ,"nil" ,CreateCValueNil),
// Los tipos compuestos, solo pueden crearse por reflexion, las listas de los tipos claves ya estan
// definidas en el switch .(Type)
/* 28 */createCTypeInfo [any ](CTypeObject ,"object" , CreateCValueObject),
/* 29 */createCTypeInfo [any ](CTypeObject ,"lazy" , CreateCValueLazy),
/* 30 */createCTypeInfo [any ](CTypeList ,"list" , CreateCValueList),
/* 31 */createCTypeInfo [any ](CTypeMap ,"map" , CreateCValueMap),
// Corresponde con el bit del flag del tipo de mapa, por lo que no puede generar un cvalue valido
//
/* 32 */createCTypeInfo[any ](CTypeInvalid,"invalid" ,createCValueInvalid,
func(i *cTypeInfo) {
i.creators[createByPtr] = createCValueInvalid
i.creators[createByList] = createCValueInvalid
i.creators[createByLazy] = createCValueInvalid
}),
},
}
}
func (i *cTypeInfos) getName(cType CType) string {
if cType.IsComposite() {
if cType.IsLazy () {
return "lazy|" + i.getName(cType.BaseType())
}
if cType.IsList () {
return "list|" + i.getName(cType.BaseType())
}
if cType.IsMap () {
k, v := cType.MapType()
return "map@" + i.getName(k) + "|" + i.getName(v)
}
}
return i.types[getPos(cType)].name
}
func (i *cTypeInfos) createCValue (value any) CValue {
if value == nil {
return CValue{ vType: CTypeAny, vState: CStateNil }
}
var f func(any) CValue
switch value.(type) {
/* Valores simples */
//case any : f = i.types[getPos(CTypeAny )].creators[createByValue]
case bool : f = i.types[getPos(CTypeBool )].creators[createByValue]
case int : f = i.types[getPos(CTypeInt )].creators[createByValue]
case int8 : f = i.types[getPos(CTypeInt8 )].creators[createByValue]
case int16 : f = i.types[getPos(CTypeInt16 )].creators[createByValue]
case int32 : f = i.types[getPos(CTypeInt32 )].creators[createByValue]
case int64 : f = i.types[getPos(CTypeInt64 )].creators[createByValue]
case uint : f = i.types[getPos(CTypeUint )].creators[createByValue]
case uint8 : f = i.types[getPos(CTypeUint8 )].creators[createByValue]
case uint16 : f = i.types[getPos(CTypeUint16 )].creators[createByValue]
case uint32 : f = i.types[getPos(CTypeUint32 )].creators[createByValue]
case uint64 : f = i.types[getPos(CTypeUint64 )].creators[createByValue]
case uintptr : f = i.types[getPos(CTypeUintptr )].creators[createByValue]
case float32 : f = i.types[getPos(CTypeFloat32 )].creators[createByValue]
case float64 : f = i.types[getPos(CTypeFloat64 )].creators[createByValue]
case complex64 : f = i.types[getPos(CTypeComplex64 )].creators[createByValue]
case complex128 : f = i.types[getPos(CTypeComplex128)].creators[createByValue]
case Date : f = i.types[getPos(CTypeDate )].creators[createByValue]
case Duration : f = i.types[getPos(CTypeDuration )].creators[createByValue]
case string : f = i.types[getPos(CTypeString )].creators[createByValue]
case Bytes : f = i.types[getPos(CTypeBytes )].creators[createByValue]
case Stack : f = i.types[getPos(CTypeStack )].creators[createByValue]
case CValue : f = i.types[getPos(CTypeCValue )].creators[createByValue]
case Packable : f = i.types[getPos(CTypePackable )].creators[createByValue]
case Context : f = i.types[getPos(CTypeContext )].creators[createByValue]
case error : f = i.types[getPos(CTypeError )].creators[createByValue]
/* Valores Listas */
case []any : f = i.types[getPos(CTypeAny )].creators[createByList]
case []bool : f = i.types[getPos(CTypeBool )].creators[createByList]
case []int : f = i.types[getPos(CTypeInt )].creators[createByList]
case []int8 : f = i.types[getPos(CTypeInt8 )].creators[createByList]
case []int16 : f = i.types[getPos(CTypeInt16 )].creators[createByList]
case []int32 : f = i.types[getPos(CTypeInt32 )].creators[createByList]
case []int64 : f = i.types[getPos(CTypeInt64 )].creators[createByList]
case []uint : f = i.types[getPos(CTypeUint )].creators[createByList]
// ya establecido como tipo base Bytes
//case []uint8 :
//
case []uint16 : f = i.types[getPos(CTypeUint16 )].creators[createByList]
case []uint32 : f = i.types[getPos(CTypeUint32 )].creators[createByList]
case []uint64 : f = i.types[getPos(CTypeUint64 )].creators[createByList]
case []uintptr : f = i.types[getPos(CTypeUintptr )].creators[createByList]
case []float32 : f = i.types[getPos(CTypeFloat32 )].creators[createByList]
case []float64 : f = i.types[getPos(CTypeFloat64 )].creators[createByList]
case []complex64: f = i.types[getPos(CTypeComplex64 )].creators[createByList]
case []complex128:f = i.types[getPos(CTypeComplex128)].creators[createByList]
case []Duration : f = i.types[getPos(CTypeDate )].creators[createByList]
case []Date : f = i.types[getPos(CTypeDuration )].creators[createByList]
case []string : f = i.types[getPos(CTypeString )].creators[createByList]
case []Bytes : f = i.types[getPos(CTypeBytes )].creators[createByList]
case []Stack : f = i.types[getPos(CTypeStack )].creators[createByList]
case []CValue : f = i.types[getPos(CTypeCValue )].creators[createByList]
case []Packable : f = i.types[getPos(CTypePackable )].creators[createByList]
case []Context : f = i.types[getPos(CTypeContext )].creators[createByList]
case []error : f = i.types[getPos(CTypeError )].creators[createByList]
/* Valores pasados por punteros */
//case *any : f = i.types[ 1/* Any */].creators[createByPtr]
case *bool : f = i.types[getPos(CTypeBool )].creators[createByPtr]
case *int : f = i.types[getPos(CTypeInt )].creators[createByPtr]
case *int8 : f = i.types[getPos(CTypeInt8 )].creators[createByPtr]
case *int16 : f = i.types[getPos(CTypeInt16 )].creators[createByPtr]
case *int32 : f = i.types[getPos(CTypeInt32 )].creators[createByPtr]
case *int64 : f = i.types[getPos(CTypeInt64 )].creators[createByPtr]
case *uint : f = i.types[getPos(CTypeUint )].creators[createByPtr]
case *uint8 : f = i.types[getPos(CTypeUint8 )].creators[createByPtr]
case *uint16 : f = i.types[getPos(CTypeUint16 )].creators[createByPtr]
case *uint32 : f = i.types[getPos(CTypeUint32 )].creators[createByPtr]
case *uint64 : f = i.types[getPos(CTypeUint64 )].creators[createByPtr]
case *uintptr : f = i.types[getPos(CTypeUintptr )].creators[createByPtr]
case *float32 : f = i.types[getPos(CTypeFloat32 )].creators[createByPtr]
case *float64 : f = i.types[getPos(CTypeFloat64 )].creators[createByPtr]
case *complex64 : f = i.types[getPos(CTypeComplex64 )].creators[createByPtr]
case *complex128: f = i.types[getPos(CTypeComplex128)].creators[createByPtr]
case *Duration : f = i.types[getPos(CTypeDate )].creators[createByPtr]
case *Date : f = i.types[getPos(CTypeDuration )].creators[createByPtr]
case *string : f = i.types[getPos(CTypeString )].creators[createByPtr]
case *Bytes : f = i.types[getPos(CTypeBytes )].creators[createByPtr]
case *Stack : f = i.types[getPos(CTypeStack )].creators[createByPtr]
case *CValue : f = i.types[getPos(CTypeCValue )].creators[createByPtr]
case *Packable : f = i.types[getPos(CTypePackable )].creators[createByPtr]
case *Context : f = i.types[getPos(CTypeContext )].creators[createByPtr]
case *error : f = i.types[getPos(CTypeError )].creators[createByPtr]
/* Valores pasados por functions Lazys */
case func()any : f = i.types[getPos(CTypeAny )].creators[createByLazy]
case func()bool : f = i.types[getPos(CTypeBool )].creators[createByLazy]
case func()int : f = i.types[getPos(CTypeInt )].creators[createByLazy]
case func()int8 : f = i.types[getPos(CTypeInt8 )].creators[createByLazy]
case func()int16 : f = i.types[getPos(CTypeInt16 )].creators[createByLazy]
case func()int32 : f = i.types[getPos(CTypeInt32 )].creators[createByLazy]
case func()int64 : f = i.types[getPos(CTypeInt64 )].creators[createByLazy]
case func()uint : f = i.types[getPos(CTypeUint )].creators[createByLazy]
case func()uint8 : f = i.types[getPos(CTypeUint8 )].creators[createByLazy]
case func()uint16 : f = i.types[getPos(CTypeUint16 )].creators[createByLazy]
case func()uint32 : f = i.types[getPos(CTypeUint32 )].creators[createByLazy]
case func()uint64 : f = i.types[getPos(CTypeUint64 )].creators[createByLazy]
case func()uintptr : f = i.types[getPos(CTypeUintptr )].creators[createByLazy]
case func()float32 : f = i.types[getPos(CTypeFloat32 )].creators[createByLazy]
case func()float64 : f = i.types[getPos(CTypeFloat64 )].creators[createByLazy]
case func()complex64: f = i.types[getPos(CTypeComplex64 )].creators[createByLazy]
case func()complex128:f = i.types[getPos(CTypeComplex128)].creators[createByLazy]
case func()Duration : f = i.types[getPos(CTypeDate )].creators[createByLazy]
case func()Date : f = i.types[getPos(CTypeDuration )].creators[createByLazy]
case func()string : f = i.types[getPos(CTypeString )].creators[createByLazy]
case func()Bytes : f = i.types[getPos(CTypeBytes )].creators[createByLazy]
case func()Stack : f = i.types[getPos(CTypeStack )].creators[createByLazy]
case func()CValue : f = i.types[getPos(CTypeCValue )].creators[createByLazy]
case func()Packable : f = i.types[getPos(CTypePackable )].creators[createByLazy]
case func()Context : f = i.types[getPos(CTypeContext )].creators[createByLazy]
case func()error : f = i.types[getPos(CTypeError )].creators[createByLazy]
default:
rv := reflect.ValueOf(value)
if !rv.IsValid() {
return createCValueWithError(value, CTypeAny,0,E.InvalidCValueReflected)
}
rt := rv.Type()
i.mux.RLock()
f,ok := i.cache[rt]
if ok {
i.mux.RUnlock()
break
}
i.mux.RUnlock()
vt := CTypeAny
switch rt.Kind() {
// Los tipos soportados deben de haber sido capturados
// por el switch de tipos
case reflect.Struct : // createCValueAny
vt = CTypeObject
case reflect.Func :
if rt.NumIn() == 0 && rt.NumOut() == 1 {
vt = CTypeLazy | CTypeAny
}
case reflect.Map :
var kt,et CType
if kt = reflectKindToCType(rt.Key().Kind(),true); kt != CTypeInvalid {
if et = reflectKindToCType(rt.Elem().Kind(),true); et != CTypeInvalid {
vt = setMapType(kt,et)
}
}
case reflect.Slice,
reflect.Array :
ke := reflectKindToCType(rt.Elem().Kind(),true)
if ke != CTypeInvalid {
vt = ke| CTypeList
}
}
f = func(v any) CValue {
t := vt
return createCValueReflected(v,reflect.ValueOf(v), t,false)
}
i.mux.Lock()
i.cache[rv.Type()] = f
i.mux.Unlock()
}
return f(value)
}
func createCValueReflected (value any, rv reflect.Value, vtype CType, check bool) CValue {
if !rv.IsValid() {
return createCValueWithError(value,vtype,0,E.InvalidCValueReflected)
}
rt := rv.Type()
vs := CStateReflected
tn := rt.String()
switch rt.Kind() {
case reflect.Slice,
reflect.Array:
if check {
if !vtype.IsList() {
return createCValueWithError(value,vtype,vs,E.InvalidCValueForType)
}
ke := reflectKindToCType(rt.Elem().Kind(), true)
if ke == CTypeInvalid {
return createCValueWithError(value,vtype,vs,E.InvalidCValueForType)
}
vtype |= ke
}
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs|=CStateNil
} else {
vs|= CStateZero
}
}
return CValue{ vType: vtype,vState: vs, anyVal: value, strVal: tn, intVal: int64(ln) }
case reflect.Map :
if check {
if !vtype.IsMap() {
return createCValueWithError(value,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
kt := reflectKindToCType(rt.Key().Kind(), true)
if kt == CTypeInvalid {
return createCValueWithError(value,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
et := reflectKindToCType(rt.Elem().Kind(), true)
if et == CTypeInvalid {
return createCValueWithError(value,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
vtype = setMapType(kt, et)
}
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs|=CStateNil
} else {
vs|= CStateZero
}
}
return CValue{ vType: vtype,vState: vs, anyVal: value, strVal: tn, intVal: int64(ln) }
case reflect.Func :
if check {
if !vtype.IsLazy() {
return createCValueWithError(value,vtype,vs,E.InvalidCValueForType)
}
if rt.NumIn() != 0 || rt.NumOut() != 1 {
return createCValueWithError(value,vtype,vs,E.InvalidCValueForType)
}
vtype = CTypeLazy | CTypeAny
}
if rv.IsNil() {
vs|=CStateNil
}
return CValue{ vType: vtype,vState: vs, strVal: tn,
anyVal: func() any {
return (rv.Call(nil))[0].Interface()
},
}
case reflect.Struct :
if check {
if !vtype.IsObject() {
return createCValueWithError(value,vtype,vs,E.InvalidCValueForType)
}
}
return CValue{vType: vtype,vState: vs, anyVal: value, strVal: tn}
case reflect.Ptr:
if rv.IsNil() {
vs|=CStateNil
}
}
return CValue{ vType: vtype,vState: vs, anyVal: value, strVal: tn }
}
func createCValueRList (rv reflect.Value, vtype CType, check bool) CValue {
vs := CStateReflected
rt := rv.Type()
tn := rt.String()
if check {
if !vtype.IsList() {
return createCValueWithError(rv,vtype,vs,E.InvalidCValueForType)
}
ke := reflectKindToCType(rt.Elem().Kind(), true)
if ke == CTypeInvalid {
return createCValueWithError(rv,vtype,vs,E.InvalidCValueForType)
}
vtype |= ke
}
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs|=CStateNil
} else {
vs|= CStateZero
}
}
return CValue{ vType: vtype,vState: vs, anyVal: rv, strVal: tn, intVal: int64(ln) }
}
func createCValueRMap (rv reflect.Value, vtype CType, check bool) CValue {
vs := CStateReflected
rt := rv.Type()
tn := rt.String()
if check {
if !vtype.IsMap() {
return createCValueWithError(rv,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
kt := reflectKindToCType(rt.Key().Kind(), true)
if kt == CTypeInvalid {
return createCValueWithError(rv,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
et := reflectKindToCType(rt.Elem().Kind(), true)
if et == CTypeInvalid {
return createCValueWithError(rv,vtype,vs|CStateInvalid,E.InvalidCValueForType)
}
vtype = setMapType(kt, et)
}
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs|=CStateNil
} else {
vs|= CStateZero
}
}
return CValue{ vType: vtype,vState: vs, anyVal: rv, strVal: tn, intVal: int64(ln) }
}
func createCValueRLazy (rv reflect.Value, vtype CType, check bool) CValue {
}
func getPos (t CType) int {
if t == 0 {
// Si 't' es CType(0) (que corresponde a CTypeInvalid),
// se le asigna el índice 0. Esto es consistente con 'cTypeInfos[0]'
// albergando la información para el tipo inválido.
return 0
}
// Calcula la posición del bit '1' más a la derecha en la representación binaria de 't'.
//
// Para los CType definidos como potencias de 2 (ej. 1 << iota, donde iota es el índice del bit),
// bits.TrailingZeros32(uint32(t)) devuelve precisamente ese índice del bit (0-based).
//
// Al sumar '+1' al resultado, convertimos este índice de bit (0-based)
// en una "posición" o "rango" basado en 1.
//
// Esto es crucial para indexar el array 'cTypeInfos [33]CTypeInfo',
// ya que:
// - CTypeInvalid (0) mapea a 'cTypeInfos[0]'.
// - El CType correspondiente al bit 0 (valor 1) mapea a 'cTypeInfos[1]'.
// - El CType correspondiente al bit 1 (valor 2) mapea a 'cTypeInfos[2]'.
// - ... y así sucesivamente, hasta el CType para el bit 31 (valor 1 << 31)
// que mapearía al índice 32, el último índice válido en el array de 33 posiciones.
return bits.TrailingZeros32(uint32(t))+1
}
func reflectKindToCType (kind reflect.Kind, base bool) CType {
switch kind {
case reflect.Invalid: return CTypeInvalid
case reflect.Bool: return CTypeBool
case reflect.Int: return CTypeInt
case reflect.Int8: return CTypeInt8
case reflect.Int16: return CTypeInt16
case reflect.Int32: return CTypeInt32
case reflect.Int64: return CTypeInt64
case reflect.Uint: return CTypeUint
case reflect.Uint8: return CTypeUint8
case reflect.Uint16: return CTypeUint16
case reflect.Uint32: return CTypeUint32
case reflect.Uint64: return CTypeUint64
case reflect.Uintptr: return CTypeUintptr
case reflect.Float32: return CTypeFloat32
case reflect.Float64: return CTypeFloat64
case reflect.Complex64: return CTypeComplex64
case reflect.Complex128:return CTypeComplex128
case reflect.String: return CTypeString
case reflect.Struct: return CTypeObject
case reflect.Array,
reflect.Slice:
if base {
return CTypeList
}
case reflect.Map:
if base {
return CTypeMap
}
case reflect.Func:
if base {
return CTypeLazy
}
}
return CTypeAny
}

@ -0,0 +1,286 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
import "math"
type (
CValue struct {
_ [0]func()
vType CType
vState CState
intVal int64
strVal string
anyVal any
}
)
func CreateCValue (value any) CValue {
return CreateCValueAny(value)
}
func CreateCValueAny (value any) CValue {
if value == nil {
return CValue{ vType: CTypeAny, vState: CStateNil }
}
return CValue{ vType: CTypeAny, anyVal: value }
}
func CreateCValueBool (value bool) CValue {
if !value {
return CValue{ vType: CTypeBool, vState: CStateZero }
}
return CValue{vType: CTypeBool, intVal: 1}
}
// Int's
func CreateCValueInt (value int) CValue {
if value == 0 {
return CValue{ vType: CTypeInt, vState: CStateZero }
}
return CValue{vType: CTypeInt, intVal: int64(value) }
}
func CreateCValueInt8 (value int8) CValue {
if value == 0 {
return CValue{ vType: CTypeInt8, vState: CStateZero }
}
return CValue{vType: CTypeInt8, intVal: int64(value)}
}
func CreateCValueInt16(value int16) CValue {
if value == 0 {
return CValue{ vType: CTypeInt16, vState: CStateZero }
}
return CValue{vType: CTypeInt16, intVal: int64(value)}
}
func CreateCValueInt32 (value int32) CValue {
if value == 0 {
return CValue{ vType: CTypeInt32, vState: CStateZero }
}
return CValue{vType: CTypeInt32, intVal: int64(value)}
}
func CreateCValueInt64 (value int64 ) CValue {
if value == 0 { return CValue{ vType: CTypeInt64, vState: CStateZero } }
return CValue{ vType: CTypeInt64, intVal: value }
}
// Uint's
func CreateCValueUint (value uint) CValue {
if value == 0 { return CValue{ vType: CTypeUint, vState: CStateZero } }
return CValue{ vType: CTypeUint, intVal: int64(value) }
}
func CreateCValueUint8 (value uint8) CValue {
if value == 0 { return CValue{ vType: CTypeUint8, vState: CStateZero } }
return CValue{ vType: CTypeUint8, intVal: int64(value) }
}
func CreateCValueUint16 (value uint16) CValue {
if value == 0 { return CValue{ vType: CTypeUint16, vState: CStateZero } }
return CValue{ vType: CTypeUint16, intVal: int64(value) }
}
func CreateCValueUint32 (value uint32) CValue {
if value == 0 { return CValue{ vType: CTypeUint32, vState: CStateZero } }
return CValue{ vType: CTypeUint32, intVal: int64(value) }
}
func CreateCValueUint64 (value uint64) CValue {
if value == 0 { return CValue{ vType: CTypeUint64, vState: CStateZero } }
return CValue{ vType: CTypeUint64, intVal: int64(value) }
}
func CreateCValueUintptr (value uintptr) CValue {
if value == 0 { return CValue{ vType: CTypeUintptr, vState: CStateZero } }
return CValue{ vType: CTypeUintptr, intVal: int64(value) }
}
// Floats
func CreateCValueFloat32 (value float32) CValue {
if value == 0.0 { // Comprobación directa para el valor cero
return CValue{vType: CTypeFloat32, vState: CStateZero}
}
return CValue{vType: CTypeFloat32, intVal: int64(math.Float32bits(value))}
}
func CreateCValueFloat64 (value float64) CValue {
if value == 0.0 { // Comprobación directa para el valor cero
return CValue{vType: CTypeFloat64, vState: CStateZero}
}
return CValue{vType: CTypeFloat64, intVal: int64(math.Float64bits(value))}
}
func CreateCValueComplex64 (value complex64) CValue {
if value == 0 { // Comprobación directa para el valor cero
return CValue{vType: CTypeComplex64, vState: CStateZero }
}
return CValue{vType: CTypeComplex64, anyVal: value}
}
func CreateCValueComplex128 (value complex128) CValue {
if value == 0 { // Comprobación directa para el valor cero
return CValue{vType: CTypeComplex128, vState: CStateZero }
}
return CValue{vType: CTypeComplex128, anyVal: value}
}
func CreateCValueDuration (value Duration) CValue {
if value == 0 {
return CValue{vType: CTypeDuration, vState: CStateZero}
}
return CValue{vType: CTypeDuration, intVal: int64(value)}
}
func CreateCValueDate (value Date) CValue {
if value.IsZero() { // Comprobación directa para el valor cero
return CValue{vType: CTypeDate, vState: CStateZero}
}
if value.After(g.minTime) && value.Before(g.maxTime) {
return CValue{vType: CTypeDate, vState: CStateShort,intVal: value.UnixNano(), anyVal: value.Location()}
}
return CValue{vType: CTypeDate, anyVal: value }
}
func CreateCValueString (value string) CValue {
if value == "" { // Comprobación directa para el valor cero
return CValue{vType: CTypeString, vState: CStateZero}
}
return CValue{vType: CTypeString, strVal: value}
}
func CreateCValueBytes (value []uint8) CValue {
l := len(value)
if l == 0 {
if value == nil {
return CValue{vType: CTypeBytes, vState: CStateNil}
} else {
return CValue{vType: CTypeBytes, vState: CStateZero,anyVal: value}
}
}
return CValue{vType: CTypeBytes, anyVal: value, intVal: int64(l)}
}
func CreateCValueStack (value Stack) CValue {
l := len(value)
if l == 0 {
if value == nil {
return CValue{vType: CTypeStack, vState: CStateNil}
} else {
return CValue{vType: CTypeStack, vState: CStateZero,anyVal: value}
}
}
return CValue{vType: CTypeStack, anyVal: value, intVal: int64(l)}
}
func createCValueCValue (value CValue) CValue {
return CValue{vType: CTypeCValue, anyVal: value } }
func CreateCValuePackable (value Packable) CValue {
if value == nil {
return CValue{vType: CTypePackable, vState: CStateNil}
}
return CValue{ vType: CTypePackable, anyVal: value }
}
func CreateCValueContext (value Context) CValue {
if value == nil {
return CValue{vType: CTypeContext, vState: CStateNil}
}
return CValue{vType: CTypeContext, anyVal: value}
}
func CreateCValueError (value error) CValue {
if value == nil {
return CValue{vType: CTypeError, vState: CStateNil}
}
return CValue{ vType: CTypeError, anyVal: value }
}
func CreateCValueNil (_ any) CValue {
return CValue{ vType: CTypeNil, vState: CStateNil }
}
func CreateCValueObject(value any) CValue {
return createCValueReflected(value,CTypeObject)
}
func CreateCValueLazy(value any) CValue {
return createCValueReflected(value,CTypeLazy)
}
func CreateCValueList(value any) CValue {
return createCValueReflected(value,CTypeList)
}
func CreateCValueMap(value any) CValue {
return createCValueReflected(value,CTypeMap)
}
func createCValueInvalid (_ any) CValue {
return CValue{ vType: CTypeInvalid, vState: CStateNil|CStateZero|CStateInvalid }
}
func createCValueWithError (value any, vtype CType, vstate CState, er string) CValue {
return CValue{
vType : CTypeInvalid,
vState: CStateInvalid|CStateError|vstate,
intVal: int64(vtype),
anyVal: value,
strVal: er,
}
}

@ -0,0 +1,50 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package cdts
import (
"context"
"time"
)
type (
Date = time.Time
Duration = time.Duration
Bytes = []uint8
Stack = []interface { m () int }
Context = context.Context
Packable = interface { a()}
MapPackable = interface { p()}
ObjectPackable = interface {}
ListPackable = interface {}
)

@ -0,0 +1,3 @@
module base
go 1.24

@ -0,0 +1,228 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 07/05/2025
// =============================================================================
// Package errs provides a robust infrastructure for structured error management
// in Go, specifically designed for distributed systems and microservices.
// It allows for hierarchical error classification, contextual metadata composition,
// and rich formatting to facilitate debugging and monitoring.
package errs
import (
"errors"
"fmt"
"io"
"regexp"
"strings"
)
const (
// errModuleSep is the separator used between the module name and the error class.
errModuleSep string = "::"
// errClassSep is the separator used between subclasses of an error.
errClassSep string = "."
// moduleName defines the default module name for internal package errors.
moduleName = errModuleSep
)
const (
// MetaClassName is the standard key name for the metadata representing the error class.
MetaClassName string = "class"
// MetaCauseName is the standard key name for the metadata representing the cause of an error.
MetaCauseName string = "cause"
// MetaStackName is the standard key name for the metadata representing the cause of an error.
MetaStackName string = "stack"
)
var (
// g contains global variables and configurations for the errs package.
g = struct {
// Regular expression validators for metadata names, subclasses, and error classes.
metaValidator,
subclassValidator,
classValidator *regexp.Regexp
// formatOptions defines the formatting options for error representation.
formatOptions *FormatOptions
// errorFormatter is the function used to format errors.
errorFormatter func(w io.Writer, e error, o *FormatOptions, l int, s FormatShow)
}{
// metaValidator checks if a metadata name is valid.
metaValidator: regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]{0,62}[a-zA-Z0-9]$`),
// classValidator checks if an error class name (including optional module) is valid.
classValidator: regexp.MustCompile(`^(?:[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?|)::[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?$`),
// subclassValidator checks if a subclass name is valid.
subclassValidator: regexp.MustCompile("^[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?$"),
// formatOptions is initialized with default color formatting options.
formatOptions: NewFormatOptionsColor(),
// errorFormatter is initialized with the default error formatting function.
errorFormatter: defaultFormatError,
}
// E contains a collection of predefined errors used internally by the errs package.
E = struct {
// Multiple indicates that an operation resulted in multiple errors.
Multiple,
// InvalidNilError indicates that a nil error was provided where not allowed.
InvalidNilError,
// InvalidClass indicates that the provided error class name is invalid.
InvalidClass,
// InvalidErrValue indicates that the provided Err value is invalid.
InvalidErrValue,
// InvalidMetaName indicates that the provided metadata name is invalid.
InvalidMetaName,
// InvalidMetaType indicates that the provided metadata type is invalid.
InvalidMetaType,
// InvalidNilCause indicates that a nil cause was provided where not allowed.
InvalidNilCause Err
}{
Multiple: Err(moduleName + "multiple_errors"),
InvalidErrValue: Err(moduleName + "invalid_err_name"),
InvalidClass: Err(moduleName + "invalid_class"),
InvalidNilError: Err(moduleName + "invalid_nil_error"),
InvalidMetaName: Err(moduleName + "invalid_meta_name"),
InvalidMetaType: Err(moduleName + "invalid_meta_type"),
InvalidNilCause: Err(moduleName + "invalid_nil_cause"),
}
)
// CreateSubclassOf creates a new subclass of an existing parent error.
// The subclass name is appended to the parent error name using errClassSep.
// Panic if the parent or subclass are not valid error names.
func CreateSubclassOf(parent Err, subclass string) Err {
if !IsValidSubclass(parent, subclass) {
panic(CreateParamErr("subclass", subclass))
}
return Err(string(parent) + errClassSep + subclass)
}
// ToError converts a value of any type to an error.
// If the value is nil, it returns nil.
// If the value is an error, it returns it directly.
// If the value is a slice of errors ([]error), it returns a composed error
// with E.Multiple and the causes attached (if the slice is not empty).
// For any other type, it uses fmt.Errorf to create a basic error.
func ToError(err any) error {
if err == nil {
return nil
}
switch e := err.(type) {
case error:
return e
case []error:
if len(e) == 0 {
return nil
}
//todo change a multiError
//return ercs.Compose(E.Multiple, ercs.WithCauses(e...))
}
return fmt.Errorf("%v", err)
}
// ErrorToString converts an error to its string representation.
// If the error is nil, it returns an empty string.
// If the error is of type Err, it returns its underlying string value.
// If the error implements fmt.Stringer, it uses its String() method.
// Otherwise, it uses the error's Error() method.
func ErrorToString(err error) string {
if err == nil {
return ""
}
switch e := err.(type) {
case Err:
return string(e)
case fmt.Stringer:
return e.String()
default:
return err.Error()
}
}
// IsSubclassOf checks if 'err' is a subclass of 'parent'.
// This is checked for both Err types (using the hierarchy defined by errClassSep)
// and standard errors (checking if the error string starts with the parent string + ".").
// Returns false if either error is nil.
func IsSubclassOf(err, parent error) bool {
if err == nil || parent == nil {
return false
}
// Specific check for Err types
var e, p Err
if errors.As(err, &e) && errors.As(parent, &p) {
return e.IsSubclassOf(p)
}
// Generic check for errors implementing Unwrap
for e := err; e != nil; e = errors.Unwrap(e) {
errStr := ErrorToString(e)
parentStr := ErrorToString(parent)
if errStr == parentStr || strings.HasPrefix(errStr, parentStr+".") {
return true
}
}
return false
}
// IsValidErr checks if a string is a valid error name according to the rules defined by classValidator.
func IsValidErr(value string) bool {
return len(value) > 0 && g.classValidator.MatchString(value)
}
// IsValidClass checks if a string is a valid class name according to the rules defined by classValidator.
func IsValidClass(class string) bool {
return len(class) > 0 && g.classValidator.MatchString(class)
}
// IsValidSubclass checks if 'subclass' is a valid subclass name for the 'parent' error.
// It verifies that both the parent and subclass are valid names and that the subclass is not identical
// to the final name of the parent (to prevent subclasses from having the same name as their direct parent).
func IsValidSubclass(parent Err, subclass string) bool {
if !IsValidErr(string(parent)) {
return false
}
if !IsValidClass(subclass) { // Should this be IsValidSubclass name?
return false
}
// Extract the final name of the parent class (e.g., "format" from "modulo::validation.format")
parentName := string(parent)
if idx := strings.LastIndex(parentName, errClassSep); idx != -1 {
parentFinalName := parentName[idx+len(errClassSep):]
return subclass != parentFinalName
}
// If no errClassSep, use the class name after errModuleSep
if c, h := strings.CutPrefix(parentName, errModuleSep); h {
return subclass != c
}
// If neither errClassSep nor errModuleSep is present, compare with the full parent name.
return subclass != parentName
}

@ -0,0 +1,45 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 17/05/2025
// =============================================================================
package errs
type (
// Causer is an interface that can be implemented by errors that have an underlying cause.
// It is similar to Go 1.13+'s Unwrap interface, but specifically for a single cause.
Causer interface {
// Cause returns the error that caused this error.
Cause() error
}
// CauseFnc is a function type that implements the Causer interface.
// It allows an anonymous function or an existing function to act as a cause.
CauseFnc func() error
)
// Cause implements the Causer interface for CauseFnc, executing the underlying function.
func (f CauseFnc) Cause() error { return f() }

@ -0,0 +1,45 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 17/05/2025
// =============================================================================
package errs
type (
// Causers is an interface that can be implemented by errors that have multiple underlying causes.
// This is useful for errors that aggregate failures from multiple operations.
Causers interface {
// Causes returns a slice of errors that caused this error.
Causes() []error
}
// CausesFnc is a function type that implements the Causers interface.
// It allows an anonymous function or an existing function to act as a provider of multiple causes.
CausesFnc func() []error
)
// Causes implements the Causers interface for CausesFnc, executing the underlying function.
func (f CausesFnc) Causes() []error { return f() }

@ -0,0 +1,129 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 07/05/2025
// =============================================================================
package errs
import (
"errors"
"strings"
)
// Err is the fundamental type for structured errors in this package.
// It represents an error with a hierarchical class name (e.g., "module::class.subclass").
// It implements the standard Go error interface.
type Err string
// CreateErr creates a new Err instance with the provided string value.
// It validates that the value is a valid error name.
// Panics if the value is not valid.
func CreateErr(value string) Err {
if !IsValidErr(value) {
// Panics with an error indicating an invalid Err value and the cause (the parameter error).
panic(E.InvalidErrValue)
}
return Err(value)
}
// Module extracts the module name from the error, if present.
// The module is the part before the first "::".
// Returns an empty string if no module is present.
func (e Err) Module() string {
// Uses strings.CutSuffix to find and remove the "::" suffix if it exists.
if m, h := strings.CutSuffix(string(e), errModuleSep); h {
return m
}
return ""
}
// Class extracts the class name from the error.
// The class is the part after the first "::", or the full name if no module is present.
func (e Err) Class() string {
s := string(e)
// Uses strings.CutPrefix to find and remove the "::" prefix if it exists.
if n, h := strings.CutPrefix(s, errModuleSep); h {
return n
}
return s
}
// Parent returns the parent error in the subclass hierarchy, if it exists.
// For example, for "module::class.subclass", it returns "module::class".
// The second boolean value is true if a parent was found, false otherwise.
func (e Err) Parent() (Err, bool) {
s := string(e)
// Finds the last class separator ".".
if idx := strings.LastIndex(s, errClassSep); idx != -1 {
// Returns the substring up to the last separator as the parent error.
return Err(s[:idx]), true
}
return "", false
}
// Error implements the standard Go error interface.
// It returns the string representation of the error.
func (e Err) Error() string { return string(e) }
// String implements the fmt.Stringer interface.
// It returns the string representation of the error.
func (e Err) String() string { return string(e) }
// IsSubclassOf checks if this Err error is a subclass of the 'parent' error.
// It checks if the string of this error starts with the string of the parent followed by the class separator ".".
// It also verifies that the errors are not identical and that this error is longer than the parent.
// Returns false if the parent is not of type Err.
func (e Err) IsSubclassOf(parent error) bool {
var p Err
// Attempts to convert the parent error to type Err.
if errors.As(parent, &p) {
s, ps := string(e), string(p)
// Checks if the string of this error starts with the parent string + "."
// and if the strings are different and this one is longer.
return s != ps && len(s) > len(ps) && strings.HasPrefix(s, ps+errClassSep)
}
return false
}
// Is implements Go 1.13+'s errors.Is interface.
// It checks if this Err error is equal to the 'target' error or if it is a subclass of 'target'.
// The exact check (e == target) is performed first.
func (e Err) Is(target error) bool {
// Exact check first: if this Err error is identical to the target (if the target is also Err).
var t Err
if errors.As(target, &t) && e == t {
return true
}
// Hierarchy check: if this error is a subclass of the target.
return IsSubclassOf(e, target)
}
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// For the base Err type, there is no wrapped error, so it returns nil.
func (_ Err) Unwrap() error { return nil }

@ -0,0 +1,122 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 13/05/2025
// =============================================================================
package errs
// ErrorList is a slice of errors with helper methods for managing the list.
// It can contain nil errors.
type ErrorList []error
// Any returns true if the list contains at least one non-nil error.
func (l ErrorList) Any() bool {
for _, e := range l {
if e != nil {
return true
}
}
return false
}
// Len returns the total length of the error list, including nil errors.
func (l ErrorList) Len() int {
return len(l)
}
// Count returns the number of non-nil errors in the list.
func (l ErrorList) Count() int {
c := 0
for _, e := range l {
if e != nil {
c++
}
}
return c
}
// First returns the first non-nil error in the list.
// If no non-nil error exists, returns nil.
func (l ErrorList) First() error {
for _, e := range l {
if e != nil {
return e
}
}
return nil
}
// Last returns the last non-nil error in the list.
// If no non-nil error exists, returns nil.
func (l ErrorList) Last() error {
for i := len(l) - 1; i >= 0; i-- {
if l[i] != nil {
return l[i]
}
}
return nil
}
// Append adds an error to the end of the list, regardless of whether it's nil.
// Returns the modified error list.
func (l ErrorList) Append(err error) ErrorList {
return append(l, err)
}
// AppendNotNil adds an error to the list only if it's not nil.
// Returns the modified error list or the original list if the error was nil.
func (l ErrorList) AppendNotNil(err error) ErrorList {
if err != nil {
return append(l, err)
}
return l
}
// Reset removes all errors from the list by resetting its length to zero.
// Returns the emptied error list.
func (l ErrorList) Reset() ErrorList {
return l[:0]
}
// Clean removes any nil errors from the list.
// Returns a new error list containing only non-nil errors.
func (l ErrorList) Clean() ErrorList {
return l.filter(func(e error) bool {
return e != nil
})
}
// filter creates a new error list containing only errors that satisfy the filter function.
// This is an internal helper method.
func (l ErrorList) filter(filter func(error) bool) ErrorList {
rs := make([]error, 0, len(l))
for _, e := range l {
if filter(e) {
rs = append(rs, e)
}
}
return rs
}

@ -0,0 +1,143 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 16/05/2025
// =============================================================================
package errs
import (
"errors"
"fmt"
"io"
"strings"
)
// Format is the main entry point for formatting errors using the package's capabilities.
// It is typically called by types implementing fmt.Formatter.
// It delegates the actual formatting to the configured errorFormatter.
func Format(err error, f fmt.State, verb rune) {
// Delegates formatting to the global errorFormatter, passing formatting state,
// the error, current format options, initial indentation level (0),
// and formatting show options derived from the fmt verb and flags.
g.errorFormatter(f, err, g.formatOptions, 0, ShowOptionsFromVerb(f, verb))
}
// defaultFormatError provides a default implementation for formatting errors.
// It recursively formats the error and its wrapped errors (causes), displaying
// error messages, metadata, and stack traces based on the provided options and show flags.
func defaultFormatError(w io.Writer, err error, opts *FormatOptions, level int, show FormatShow) {
if err == nil {
return
}
var el []error // Slice to collect wrapped errors (causes) for recursive formatting
var stack *Meta // Pointer to store the stack trace metadata if found
// Determine which metadata to select based on show options.
sm := MetaTypeValue
if show.ShowStack() {
sm |= MetaTypeStack
}
// If not showing hierarchy, don't select cause metadata at the current level
// to avoid duplicating cause information in the flat metadata list.
if !show.ShowHierarchy() {º
sm |= MetaTypeCause
}
// Calculate the indentation for the current level.
indent := strings.Repeat(opts.Indent, level)
// Format the current error message. Use different formats for the root error (level 0) and causes.
if level == 0 {
_, _ = fmt.Fprintf(w, opts.FmtError, indent, err.Error())
} else {
_, _ = fmt.Fprintf(w, opts.FmtCause, indent, err.Error())
}
// Iterate through the error chain using errors.Unwrap.
for e := err; e != nil; e = errors.Unwrap(e) {
// If showing metadata and the current error provides metadata.
if show.ShowMetas() {
if mp, ok := e.(MetadataProvider); ok {
// Get metadata based on the current selection criteria.
ml := mp.Metadata(sm)
for _, m := range ml {
// Handle stack trace metadata separately if selected.
if sm.SelectStack() && m.mType == MetaTypeStack {
stack = &m
// Remove MetaSelectStack from selection for subsequent metadata at this level.
sm &^= MetaTypeStack
continue
}
// If showing hierarchy, skip cause metadata here to avoid duplication.
if show.ShowHierarchy() && sm.SelectCause() && m.mType == MetaTypeCause {
continue
}
// Format other metadata.
_, _ = fmt.Fprintf(w, opts.FmtMeta, indent, m.Name, m.Value())
}
}
}
// If showing hierarchy, collect the wrapped errors (causes) for recursive formatting.
if show.ShowHierarchy() {
switch cs := e.(type) {
case Causer:
// Handle single cause errors.
el = append(el, cs.Cause())
case Causers:
// Handle errors with multiple causes.
el = append(el, cs.Causes()...)
case interface{ Unwrap() []error }:
// Handle errors implementing the Unwrap() []error interface (Go 1.20+).
el = cs.Unwrap()
}
}
}
// Recursively format the collected wrapped errors (causes).
if len(el) > 0 {
// Adjust show options for deep formatting if not explicitly requested.
if !show.ShowDeepMetas() && show.ShowMetas() {
show &^= FormatShowMetas // Turn off showing metas in deeper levels if not deep.
}
if !show.ShowDeepStacks() && show.ShowStack() {
show &^= FormatShowStack // Turn off showing stacks in deeper levels if not deep.
}
for _, ce := range el {
// Recursively call defaultFormatError for each cause, increasing the indentation level.
defaultFormatError(w, ce, opts, level+1, show)
}
}
// Format the stack trace if one was collected and formatting is enabled.
if stack != nil && !stack.State().HasNilOrZero() {
_, _ = fmt.Fprintf(w, opts.FmtStackH, indent) // Format stack header.
// Format each line of the stack trace.
for _, l := range stack.Value().([]string) {
_, _ = fmt.Fprintf(w, opts.FmtStackL, indent, l)
}
}
}

@ -0,0 +1,131 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 17/05/2025
// =============================================================================
package errs
/*
// Basic ANSI color codes (Commented out, but values used in NewFormatOptionsColor)
const (
ColorBlack = "\033[30m"
ColorRed = "\033[31m"
ColorGreen = "\033[32m"
ColorYellow = "\033[33m"
ColorBlue = "\033[34m"
ColorMagenta = "\033[35m"
ColorCyan = "\033[36m"
ColorWhite = "\033[37m"
ColorGray = "\033[2m"
ColorBrightBlack = "\033[90m"
ColorBrightRed = "\033[91m"
ColorBrightGreen = "\033[92m"
ColorBrightYellow = "\033[93m"
ColorBrightBlue = "\033[94m"
ColorBrightMagenta= "\033[95m"
ColorBrightCyan = "\033[96m"
ColorBrightWhite = "\033[97m"
BgBlack = "\033[40m"
BgRed = "\033[41m"
BgGreen = "\033[42m"
BgYellow = "\033[43m"
BgBlue = "\033[44m"
BgMagenta = "\033[45m"
BgCyan = "\033[46m"
BgWhite = "\033[47m"
BgBrightBlack = "\033[100m"
BgBrightRed = "\033[101m"
BgBrightGreen = "\033[102m"
BgBrightYellow = "\033[103m"
BgBrightBlue = "\033[104m"
BgBrightMagenta = "\033[105m"
BgBrightCyan = "\033[106m"
BgBrightWhite = "\033[107m"
TextBold = "\033[1m" // Bold text
TextFaint = "\033[2m" // Faint text (dim)
TextUnderline = "\033[4m" // Underlined text
TextReverse = "\033[7m" // Swap foreground and background colors
ColorReset = "\033[0m" // Reset all attributes
)
*/
type (
// FormatOptions defines the options for controlling how errors are formatted.
FormatOptions struct {
// Show specifies which parts of the error (hierarchy, metas, stack) should be displayed.
Show FormatShow
// EnableColor indicates whether ANSI color codes should be included in the output.
EnableColor bool
// Indent is the string used for each level of indentation in the formatted output.
Indent string
// FmtError is the format string used for the root error message.
FmtError string
// FmtMeta is the format string used for displaying metadata.
FmtMeta string
// FmtCause is the format string used for displaying wrapped error messages (causes).
FmtCause string
// FmtStackH is the format string used for the stack trace header.
FmtStackH string
// FmtStackL is the format string used for each line of the stack trace.
FmtStackL string
}
)
// NewFormatOptions creates a new FormatOptions instance with default plain text formatting.
func NewFormatOptions() *FormatOptions {
return &FormatOptions{
Indent: " ",
FmtError: "%s%s\n",
FmtMeta: "%s * %s: %v\n",
FmtCause: "%s%s\n",
FmtStackH: "%s * stack:\n",
FmtStackL: "%s %s\n",
}
}
// NewFormatOptionsColor creates a new FormatOptions instance with default ANSI color formatting.
func NewFormatOptionsColor() *FormatOptions {
return &FormatOptions{
Indent: " ",
EnableColor: true,
// Format strings include ANSI color codes for different parts of the error output.
FmtError: "%s\033[31m%s\033[0m\n", // Red for the main error message
FmtMeta: "%s\033[2m * %s: %v\033[0m\n", // Faint/Dim for metadata
FmtCause: "%s\033[33m%s\033[0m\n", // Yellow for wrapped error messages (causes)
FmtStackH: "%s\033[37m * stack:\033[0m\n", // White for stack header
FmtStackL: "%s\033[37m %s\033[0m\n", // White for stack lines
}
}

@ -0,0 +1,93 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n// =============================================================================\n// Date Create 18/05/2025\n// =============================================================================
package errs
import "fmt"
const (
// FormatShowHierarchy is a flag to show the error hierarchy (wrapped errors/causes).
FormatShowHierarchy FormatShow = 1 << iota
// FormatShowMetas is a flag to show metadata of the current error in the hierarchy.
FormatShowMetas
// FormatShowDeepMetas is a flag to show metadata for all errors in the hierarchy.
FormatShowDeepMetas
// FormatShowStack is a flag to show the stack trace of the root error.
FormatShowStack
// FormatShowDeepStacks is a flag to show stack traces for all errors in the hierarchy if defined.
FormatShowDeepStacks
// FormatShowNone is a flag to show nothing extra (only the basic error message).
FormatShowNone FormatShow = 0
)
// FormatShow is a bitmask type used to control which parts of an error are displayed during formatting.
type FormatShow uint8
// ShowMetas returns true if the FormatShow includes the FormatShowMetas flag.
func (o FormatShow) ShowMetas() bool { return o&FormatShowMetas != 0 }
// ShowHierarchy returns true if the FormatShow includes the FormatShowHierarchy flag.
func (o FormatShow) ShowHierarchy() bool { return o&FormatShowHierarchy != 0 }
// ShowDeepMetas returns true if the FormatShow includes the FormatShowDeepMetas flag.
func (o FormatShow) ShowDeepMetas() bool { return o&FormatShowDeepMetas != 0 }
// ShowStack returns true if the FormatShow includes the FormatShowStack flag.
func (o FormatShow) ShowStack() bool { return o&FormatShowStack != 0 }
// ShowDeepStacks returns true if the FormatShow includes the FormatShowDeepStacks flag.
func (o FormatShow) ShowDeepStacks() bool { return o&FormatShowDeepStacks != 0 }
// ShowOptionsFromVerb derives FormatShow options based on the fmt.State and verb.
// This function interprets standard fmt verbs and flags to determine what to display.
func ShowOptionsFromVerb(f fmt.State, verb rune) FormatShow {
s := FormatShowNone
switch verb {
case 's', 'q':
// For %s and %q, show nothing extra.
return s
case 'v':
// For %v, check flags to determine what to show.
if f.Flag('+') {
// %+v -> Show hierarchy, metas, and full stack
s |= FormatShowHierarchy |
FormatShowMetas |
FormatShowDeepMetas |
FormatShowStack |
FormatShowDeepStacks
} else if f.Flag('#') {
// %#v -> Show metas and stack of the principal error
s |= FormatShowMetas |
FormatShowStack
} else {
// %v -> Show hierarchy and principal stack (optional based on your criterion)
s |= FormatShowHierarchy |
FormatShowStack
}
}
return s
}

@ -0,0 +1,47 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 20/05/2025
// =============================================================================
package errs
type (
Formatter interface {
Format (err error) ([]byte,error)
}
FormatFnc func (error) ([]byte,error)
)
func (f FormatFnc) Format (err error) ([]byte,error) { return f(err) }

@ -0,0 +1,86 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 09/06/2025
// =============================================================================
package errs
import (
"core/excs"
"core/vals"
)
type (
Meta struct {
vals.CValue
name string
mType MetaType
}
)
func CreateMeta (name string, cval vals.CValue) Meta {
if !IsValidMetaName(name) {
panic(E.InvalidMetaName)
}
return Meta {
CValue : cval,
name : name,
mType : MetaTypeValue,
}
}
func CreateMetaStack (stack excs.Stack) Meta {
return Meta {
name : MetaCauseName,
CValue : vals.CreateCValueStack(stack),
mType : MetaTypeStack,
}
}
func CreateMetaCause(cause error) Meta {
return Meta {
name : MetaCauseName,
CValue : vals.CreateCValueError(cause),
mType : MetaTypeCause,
}
}
func (m Meta) Name() string { return m.name }
// IsValidMetaName checks if a string is a valid metadata name according to the rules defined by metaValidator.
func IsValidMetaName(meta string) bool {
return len(meta) > 0 && g.metaValidator.MatchString(meta)
}

@ -0,0 +1,52 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 18/05/2025
// =============================================================================
package errs
const (
// MetaTypeValue is a flag to select general value metadata.
MetaTypeValue MetaType = 1 << iota
// MetaTypeCause is a flag to select cause metadata.
MetaTypeCause
// MetaTypeStack is a flag to select stack trace metadata.
MetaTypeStack
// MetaTypeAll is a flag to select all types of metadata.
MetaTypeAll = 7 // Combination of all selection flags
)
// MetaType is a bitmask type used to select which types of metadata to retrieve.
type MetaType uint8
// SelectValue returns true if the MetaType includes the MetaTypeValue flag.
func (s MetaType) SelectValue() bool { return s&MetaTypeValue != 0 }
// SelectCause returns true if the MetaType includes the MetaTypeCause flag.
func (s MetaType) SelectCause() bool { return s&MetaTypeCause != 0 }
// SelectStack returns true if the MetaType includes the MetaTypeStack flag.
func (s MetaType) SelectStack() bool { return s&MetaTypeStack != 0 }

@ -0,0 +1,45 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 16/05/2025
// =============================================================================
package errs
type (
// MetadataProvider is an interface implemented by types that can provide metadata.
// Composed error types typically implement this interface.
MetadataProvider interface {
// Metadata returns a slice of Meta objects based on the provided selector.
Metadata(selector MetaType) []Meta }
// MetadataFnc is a function type that implements the MetadataProvider interface.
// It allows an anonymous function or an existing function to act as a metadata provider.
MetadataFnc func(selector MetaType) []Meta
)
// Metadata implements the MetadataProvider interface for MetadataFnc, executing the underlying function.
func (f MetadataFnc) Metadata(selector MetaType) []Meta { return f(selector) }

@ -0,0 +1,72 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 13/05/2025
// =============================================================================
package errs
const (
// errPanic is the error class name used to represent panics converted to errors.
errPanic = moduleName + "panic"
)
type (
// PanicErr is an error type that wraps a recovered panic.
// It allows treating a panic as a structured error.
PanicErr struct {
Err // Embeds the Err type to inherit its methods and basic structure.
cause error // cause stores the recovered panic value, converted to an error type.
}
)
// CreatePanicErr creates a new PanicErr instance from a recovered panic value.
// It converts the panic value to an error type using ToError.
func CreatePanicErr(cause any) PanicErr {
return PanicErr{
Err: CreateErr(errPanic), // Creates a base error with the "panic" class.
cause: ToError(cause), // Converts the panic value to an error.
}
}
// Cause implements the Causer interface for PanicErr.
// It returns the underlying error representing the panic value.
func (e PanicErr) Cause() error { return e.cause }
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// It returns the underlying error representing the panic value, allowing
// the PanicErr to be unwrapped to access the original cause.
func (e PanicErr) Unwrap() error { return e.cause }
func (e PanicErr) Metadata(selector MetaType) []Meta {
if !selector.SelectCause() {
return nil
}
return []Meta{
CreateMetaCause(e.cause),
}
}

@ -0,0 +1,111 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 12/05/2025
// =============================================================================
package errs
import (
"core/vals"
"fmt"
)
const (
errParam = moduleName + "invalid_param"
errParamNil = errParam + errClassSep + "nil"
errParamEmpty = errParam + errClassSep + "empty"
errParamRange = errParam + errClassSep + "range"
errParamRangeMin = errParamRange + errClassSep + "min"
errParamRangeMax = errParamRange + errClassSep + "max"
)
type (
ParamErr struct {
Err
name string
value any
}
)
func createParamErr(err Err, name string, value any) ParamErr {
if name == "" {
panic(CreateParamEmptyErr("name"))
}
return ParamErr{
Err: err,
name: name,
value: value,
}
}
func CreateParamErr (name string, value any) ParamErr {
return createParamErr(Err(errParam), name, value)
}
func CreateParamNilErr (name string) ParamErr {
return createParamErr(Err(errParamNil),name, nil)
}
func CreateParamEmptyErr(name string) ParamErr {
return createParamErr(Err(errParamEmpty),name,"")
}
func CreateParamRange (name string, value any) ParamErr {
return createParamErr(Err(errParamRange),name,value)
}
func CreateParamRangeMin(name string, value any) ParamErr {
return createParamErr(Err(errParamRangeMin), name, value)
}
func CreateParamRangeMax(name string, value any) ParamErr {
return createParamErr(Err(errParamRangeMax), name, value)
}
func (e ParamErr) ParamName() string { return e.name }
func (e ParamErr) ParamValue() any { return e.value }
func (e ParamErr) Format(f fmt.State, v rune) { Format(e, f, v) }
func (e ParamErr) Metadata(selector MetaType) []Meta {
if !selector.SelectValue() {
return nil
}
return []Meta {
CreateMeta("param_name", vals.CreateCValueString(e.name)),
vals.CreateCField("param_value", e.value),
}
}
func (e ParamErr) Unwrap() error {
// ParamErr es típicamente un error hoja, no envuelve nada que continúe la cadena.
return nil
}

@ -0,0 +1,60 @@
// =============================================================================
// Active-GO Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 15/05/2025
// =============================================================================
package errs
const (
// SeverityDebug indicates a severity level for debugging information.
SeverityDebug Severity = 1 << iota
// SeverityInfo indicates a severity level for general information.
SeverityInfo
// SeverityWarn indicates a severity level for warnings.
SeverityWarn
// SeverityError indicates a severity level for errors affecting functionality.
SeverityError
// SeverityCritical indicates a severity level for critical errors requiring immediate attention.
SeverityCritical
// SeverityFatal indicates a severity level for errors causing application termination.
SeverityFatal
)
// Severity represents the severity level of an error.
// It is used to classify the importance of an error.
type Severity uint8
// String returns the string representation of the severity level.
// Returns "UNKNOWN" for undefined severity values.
func (s Severity) String() string {
// Checks if the severity value is within the expected range.
if s <= 0 || s > SeverityFatal {
return "UNKNOWN"
}
// Uses a string slice to map the severity value to its name.
// Note: Index 0 is not used as severity values start from 1 (1 << 0).
return [...]string{"DEBUG", "INFO", "WARNING", "ERROR", "FATAL", "CRITICAL"}[s-1] // Corrected index
}

@ -26,8 +26,8 @@
// Date Create 28/05/2025
// =============================================================================
package blrs
package pkrs
type ListBaler interface {
Add() Baler
type ListPacker interface {
Add() Packer
}

@ -26,8 +26,8 @@
// Date Create 28/05/2025
// =============================================================================
package blrs
package pkrs
type MapBaler interface {
Key(key any) Baler
type MapPacker interface {
Key(key any) Packer
}

@ -26,8 +26,8 @@
// Date Create 28/05/2025
// =============================================================================
package blrs
package pkrs
type ObjectBaler interface {
Field(name string) Baler
type ObjectPacker interface {
Field(name string) Packer
}

@ -26,8 +26,10 @@
// Date Create 28/05/2025
// =============================================================================
package blrs
package pkrs
type Baleable interface {
Bale(baler Baler) error
type Packable interface {
Pack(packer Packer) error
}

@ -26,10 +26,13 @@
// Date Create 28/05/2025
// =============================================================================
package blrs
package pkrs
type Baler interface {
Map(mapBaler MapBaler) error
List(listBaler ListBaler) error
Object(objBaler ObjectBaler) error
}
type (
Packer interface {
Map (mapPacker MapPacker) error
List (listPacker ListPacker) error
Object (objPacker ObjectPacker) error
}
)

@ -28,14 +28,25 @@
package vals
import (
"math"
"time"
)
var (
G = struct {
TypeInfos *CValueTypeInfos
g = struct {
minTime,
maxTime time.Time
}{
minTime: time.Unix(0, math.MinInt64),
maxTime: time.Unix(0, math.MaxInt64),
}
G = struct {
TypeInfos *CValueTypeInfos
}{
TypeInfos: newCValueTypeInfos(),
}

@ -0,0 +1,154 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package vals
type (
CAttribute struct {
CValue
aType CAttributeType
name string
}
)
func CreateCAttribute (name string, value any, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValue(value), attrType)
}
func CreateCAttributeBool (name string, value bool, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueBool(value), attrType) }
func CreateCAttributeInt (name string, value int, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueInt(value), attrType) }
func CreateCAttributeInt8 (name string, value int8, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueInt8(value), attrType) }
func CreateCAttributeInt16 (name string, value int16, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueInt16(value), attrType) }
func CreateCAttributeInt32 (name string, value int32, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueInt32(value), attrType) }
func CreateCAttributeInt64 (name string, value int64, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueInt64(value), attrType) }
func CreateCAttributeUint (name string, value uint, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUint(value), attrType) }
func CreateCAttributeUint8 (name string, value uint8, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUint8(value), attrType) }
func CreateCAttributeUint16 (name string, value uint16, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUint16(value), attrType) }
func CreateCAttributeUint32 (name string, value uint32, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUint32(value), attrType) }
func CreateCAttributeUint64 (name string, value uint64, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUint64(value), attrType) }
func CreateCAttributeUintptr (name string, value uintptr, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueUintptr(value),attrType) }
func CreateCAttributeFloat32 (name string, value float32, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueFloat32(value), attrType) }
func CreateCAttributeFloat64 (name string, value float64, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueFloat64(value), attrType) }
func CreateCAttributeComplex64 (name string, value complex64, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueComplex64(value), attrType) }
func CreateCAttributeComplex128 (name string, value complex128, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueComplex128(value), attrType) }
func CreateCAttributeDate (name string, value Date, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueDate(value),attrType) }
func CreateCAttributeDuration (name string, value Duration, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueDuration(value),attrType) }
func CreateCAttributeString (name string, value string, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueString(value), attrType) }
func CreateCAttributeBytes (name string, value Bytes, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueBytes(value), attrType) }
func CreateCAttributeStack (name string, value Stack, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueStack(value), attrType | CAttributeTypeStack ) }
func CreateCAttributeCause (name string, value error, attrType CAttributeType) CAttribute {
return CreateCAttributeWithCValue(name,CreateCValueError(value), attrType|CAttributeTypeCause) }
func CreateCAttributeWithCValue (name string, cvalue CValue, attrType CAttributeType) CAttribute {
at := CAttribute{
CValue: cvalue,
name : name,
aType : attrType,
}
if attrType.HasAttributePII() {
at.vState|= cValueStateSensitive
}
return at
}
func (a CAttribute) Name() string { return a.name }
func (a CAttribute) AttrType() CAttributeType { return a.aType }

@ -0,0 +1,74 @@
// =============================================================================
// GO·AT Framework
// Copyright (c) 2025 ActiveThing (https://activething.com)
// Author: Juan V. Navarro juanvnl@activething.com
// =============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// =============================================================================
// Date Create 10/06/2025
// =============================================================================
package vals
const (
CAttributeTypeCause CAttributeType = 1 << iota
CAttributeTypeStack
CAttributeTypeIdentifier
CAttributeTypeIndexed
CAttributeTypeMeasurement
CAttributeTypePII
CAttributeTypeDebug
CAttributeTypeDefault CAttributeType = 0
)
type CAttributeType uint8
func (c CAttributeType) HasAttribute (attType CAttributeType) bool { return c&attType == c }
func (c CAttributeType) IsAttributeDefault () bool { return c == 0 }
func (c CAttributeType) HasAttributeCause () bool { return c&CAttributeTypeCause != 0 }
func (c CAttributeType) HasAttributeStack () bool { return c&CAttributeTypeStack != 0 }
func (c CAttributeType) HasAttributeIdentifier() bool { return c&CAttributeTypeIdentifier != 0 }
func (c CAttributeType) HasAttributePII () bool { return c&CAttributeTypePII != 0 }
func (c CAttributeType) HasAttributeIndexed () bool { return c&CAttributeTypeIndexed != 0 }
func (c CAttributeType) HasAttributeMeasurement() bool{ return c&CAttributeTypeMeasurement != 0 }
func (c CAttributeType) HasAttributeDebug () bool { return c&CAttributeTypeDebug != 0 }

@ -35,9 +35,23 @@ type (
CField struct {
Name string
Value CValue
CValue
}
)
func CreateCField (name string, value any) CField {
return CField{
Name : name,
CValue: CreateCValue(value),
}
}
func CreateCFieldWithCValue (name string, cvalue CValue) CField {
return CField{
Name : name,
CValue: cvalue,
}
}

@ -29,7 +29,6 @@
package vals
import (
"core/blrs"
"core/excs"
"math"
"reflect"
@ -39,8 +38,8 @@ import (
type CValue struct {
_ [0]func()
vType CValueType
vState CValueState
vType CValueType
vState CValueState
intVal int64
strVal string
anyVal any
@ -54,14 +53,14 @@ func CreateCValue(value any) CValue {
func createCValueAny (value any ) CValue {
if value == nil { return CValue{ vType: CValueTypeAny, vState: cValueStateNil|cValueStateZero } }
return CValue{ vType: CValueTypeAny, anyVal: value }
if value == nil { return CValue{ vType: cValueTypeAny, vState: cValueStateNil|cValueStateZero } }
return CValue{ vType: cValueTypeAny, anyVal: value }
}
func CreateCValueBool (value bool ) CValue {
if !value { return CValue{ vType: CValueTypeInt, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt, vState: cValueStateZero, intVal: 1}
if !value { return CValue{ vType: cValueTypeInt, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt, vState: cValueStateZero, intVal: 1}
}
@ -69,28 +68,28 @@ func CreateCValueBool (value bool ) CValue {
// Int's
func CreateCValueInt (value int ) CValue {
if value == 0 { return CValue{ vType: CValueTypeInt, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeInt, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt, intVal: int64(value) }
}
func CreateCValueInt8 (value int8 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeInt8, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt8, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeInt8, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt8, intVal: int64(value) }
}
func CreateCValueInt16 (value int16 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeInt16, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt16, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeInt16, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt16, intVal: int64(value) }
}
func CreateCValueInt32 (value int32 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeInt32, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt32, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeInt32, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt32, intVal: int64(value) }
}
func CreateCValueInt64 (value int64 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeInt64, vState: cValueStateZero } }
return CValue{ vType: CValueTypeInt64, intVal: value }
if value == 0 { return CValue{ vType: cValueTypeInt64, vState: cValueStateZero } }
return CValue{ vType: cValueTypeInt64, intVal: value }
}
@ -98,34 +97,34 @@ func CreateCValueInt64 (value int64 ) CValue {
// Uint's
func CreateCValueUint (value uint ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUint, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUint, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUint, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUint, intVal: int64(value) }
}
func CreateCValueUint8 (value uint8 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUint8, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUint8, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUint8, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUint8, intVal: int64(value) }
}
func CreateCValueUint16 (value uint16 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUint16, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUint16, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUint16, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUint16, intVal: int64(value) }
}
func CreateCValueUint32 (value uint32 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUint32, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUint32, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUint32, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUint32, intVal: int64(value) }
}
func CreateCValueUint64 (value uint64 ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUint64, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUint64, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUint64, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUint64, intVal: int64(value) }
}
func CreateCValueUintptr (value uintptr ) CValue {
if value == 0 { return CValue{ vType: CValueTypeUintptr, vState: cValueStateZero } }
return CValue{ vType: CValueTypeUintptr, intVal: int64(value) }
if value == 0 { return CValue{ vType: cValueTypeUintptr, vState: cValueStateZero } }
return CValue{ vType: cValueTypeUintptr, intVal: int64(value) }
}
@ -133,67 +132,67 @@ func CreateCValueUintptr (value uintptr ) CValue {
func CreateCValueFloat32 (value float32 ) CValue {
if value == 0.0 { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeFloat32, vState: cValueStateZero}
return CValue{vType: cValueTypeFloat32, vState: cValueStateZero}
}
return CValue{vType: CValueTypeFloat32, intVal: int64(math.Float32bits(value))}
return CValue{vType: cValueTypeFloat32, intVal: int64(math.Float32bits(value))}
}
func CreateCValueFloat64 (value float64 ) CValue {
if value == 0.0 { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeFloat64, vState: cValueStateZero}
return CValue{vType: cValueTypeFloat64, vState: cValueStateZero}
}
return CValue{vType: CValueTypeFloat64, intVal: int64(math.Float64bits(value))}
return CValue{vType: cValueTypeFloat64, intVal: int64(math.Float64bits(value))}
}
func CreateCValueComplex64 (value complex64 ) CValue {
if value == 0 { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeComplex64, vState: cValueStateZero }
return CValue{vType: cValueTypeComplex64, vState: cValueStateZero }
}
return CValue{vType: CValueTypeComplex64, anyVal: value}
return CValue{vType: cValueTypeComplex64, anyVal: value}
}
func CreateCValueComplex128 (value complex128) CValue {
if value == 0 { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeComplex128, vState: cValueStateZero }
return CValue{vType: cValueTypeComplex128, vState: cValueStateZero }
}
return CValue{vType: CValueTypeComplex128, anyVal: value}
return CValue{vType: cValueTypeComplex128, anyVal: value}
}
func CreateCValueDuration (value Duration ) CValue {
if value == 0 {
return CValue{vType: CValueTypeDuration, vState: cValueStateZero}
return CValue{vType: cValueTypeDuration, vState: cValueStateZero}
}
return CValue{vType: CValueTypeDuration, intVal: int64(value)}
return CValue{vType: cValueTypeDuration, intVal: int64(value)}
}
func CreateCValueDate (value Date ) CValue {
if value.IsZero() { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeDate, vState: cValueStateZero}
return CValue{vType: cValueTypeDate, vState: cValueStateZero}
}
if value.After(G.TypeInfos.minTime) && value.Before(G.TypeInfos.maxTime) {
return CValue{vType: CValueTypeDate, vState: cValueStateShort,intVal: value.UnixNano(), anyVal: value.Location()}
if value.After(g.minTime) && value.Before(g.maxTime) {
return CValue{vType: cValueTypeDate, vState: cValueStateShort,intVal: value.UnixNano(), anyVal: value.Location()}
}
return CValue{vType: CValueTypeDate, anyVal: value }
return CValue{vType: cValueTypeDate, anyVal: value }
}
func CreateCValueString (value string ) CValue {
if value == "" { // Comprobación directa para el valor cero
return CValue{vType: CValueTypeString, vState: cValueStateZero}
return CValue{vType: cValueTypeString, vState: cValueStateZero}
}
return CValue{vType: CValueTypeString, strVal: value}
return CValue{vType: cValueTypeString, strVal: value}
}
func CreateCValueBytes (value []uint8 ) CValue {
l := len(value)
if l == 0 {
if value == nil {
return CValue{vType: CValueTypeBytes, vState: cValueStateNil}
return CValue{vType: cValueTypeBytes, vState: cValueStateNil}
} else {
return CValue{vType: CValueTypeBytes, vState: cValueStateZero,anyVal: value}
return CValue{vType: cValueTypeBytes, vState: cValueStateZero,anyVal: value}
}
}
return CValue{vType: CValueTypeBytes, anyVal: value, intVal: int64(l)}
return CValue{vType: cValueTypeBytes, anyVal: value, intVal: int64(l)}
}
@ -201,59 +200,59 @@ func CreateCValueStack (value Stack ) CValue {
l := len(value)
if l == 0 {
if value == nil {
return CValue{vType: CValueTypeStack, vState: cValueStateNil}
return CValue{vType: cValueTypeStack, vState: cValueStateNil}
} else {
return CValue{vType: CValueTypeStack, vState: cValueStateZero,anyVal: value}
return CValue{vType: cValueTypeStack, vState: cValueStateZero,anyVal: value}
}
}
return CValue{vType: CValueTypeStack, anyVal: value, intVal: int64(l)}
return CValue{vType: cValueTypeStack, anyVal: value, intVal: int64(l)}
}
func CreateCValueBaleable (value Baleable ) CValue {
func CreateCValuePackable (value Packable) CValue {
if value == nil {
return CValue{vType: CValueTypeBaleable, vState: cValueStateNil}
return CValue{vType: cValueTypePackable, vState: cValueStateNil}
}
return CValue{ vType: CValueTypeBaleable, anyVal: value }
return CValue{ vType: cValueTypePackable, anyVal: value }
}
func CreateCValueError (value error ) CValue {
if value == nil {
return CValue{vType: CValueTypeError, vState: cValueStateNil}
return CValue{vType: cValueTypeError, vState: cValueStateNil}
}
return CValue{ vType: CValueTypeError, anyVal: value }
return CValue{ vType: cValueTypeError, anyVal: value }
}
func CreateCValueNil (_ any ) CValue { return CValue{ vType: CValueTypeNil, vState: cValueStateNil } }
func CreateCValueNil (_ any ) CValue { return CValue{ vType: cValueTypeNil, vState: cValueStateNil } }
func createCValueCValue (value CValue ) CValue { return CValue{vType: CValueTypeCValue, anyVal: value } }
func createCValueCValue (value CValue ) CValue { return CValue{vType: cValueTypeCValue, anyVal: value } }
func createCValueCField (value CField ) CValue { return CValue{vType: CValueTypeCField, anyVal: value} }
func createCValueCField (value CField ) CValue { return CValue{vType: cValueTypeCField, anyVal: value} }
func createCValueObject (value any ) CValue {
return createCValueReflected(value,reflect.ValueOf(value),CValueTypeObject, true) }
return createCValueReflected(value,reflect.ValueOf(value), cValueTypeObject, true) }
func CreateCValueList (value any) CValue {
return createCValueReflected (value,reflect.ValueOf(value),CValueTypeList , true)
return createCValueReflected (value,reflect.ValueOf(value), cValueTypeList, true)
}
func CreateCValueDefer (value any) CValue {
return createCValueReflected (value,reflect.ValueOf(value),CValueTypeDefer ,true)
return createCValueReflected (value,reflect.ValueOf(value), cValueTypeDefer,true)
}
func CreateCValueMap (value any) CValue {
return createCValueReflected (value,reflect.ValueOf(value),CValueTypeMap , true)
return createCValueReflected (value,reflect.ValueOf(value), cValueTypeMap, true)
}
func createCValueInvalid (value any) CValue {
return CValue{ vType: CValueTypeInvalid, anyVal: value}
return CValue{ vType: cValueTypeInvalid, anyVal: value}
}
func createCValueWithInvalidError (value any, vtype CValueType, vstate CValueState, er string) CValue {
return CValue{
vType : CValueTypeInvalid,
vType : cValueTypeInvalid,
vState: cValueStateInvalid|cValueStateError|vstate,
intVal: int64(vtype),
anyVal: value,
@ -264,15 +263,22 @@ func createCValueWithInvalidError (value any, vtype CValueType, vstate CValueSta
func (v CValue) Type () CValueType { return v.vType }
func (v CValue) Type () CValueType { return v.vType }
func (v CValue) State() CValueState { return v.vState }
func (v CValue) Value() any {
// devolvemos en funcion del tipo de value
// todo
return v.anyVal
}
func (v CValue) AsBool () (bool,bool){
if v.vType != CValueTypeBool {
if v.vType != cValueTypeBool {
return false,false
}
if v.vState.HasNilOrZero() {
@ -287,7 +293,7 @@ func (v CValue) AsBool () (bool,bool){
func (v CValue) AsInt () (int,bool){
if v.vType != CValueTypeInt {
if v.vType != cValueTypeInt {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -300,10 +306,10 @@ func (v CValue) AsInt () (int,bool){
}
func (v CValue) AsInts () ([]int,bool){
if v.vType != CValueTypeInt|CValueTypeList {
if v.vType != cValueTypeInt|cValueTypeList {
return nil,false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return nil,true
}
return v.anyVal.([]int),true
@ -311,7 +317,7 @@ func (v CValue) AsInts () ([]int,bool){
func (v CValue) AsInt8 () (int8,bool){
if v.vType != CValueTypeInt8 {
if v.vType != cValueTypeInt8 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -324,7 +330,7 @@ func (v CValue) AsInt8 () (int8,bool){
}
func (v CValue) AsInt16 () (int16,bool){
if v.vType != CValueTypeInt16 {
if v.vType != cValueTypeInt16 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -337,7 +343,7 @@ func (v CValue) AsInt16 () (int16,bool){
}
func (v CValue) AsInt32 () (int32,bool){
if v.vType != CValueTypeInt32 {
if v.vType != cValueTypeInt32 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -350,7 +356,7 @@ func (v CValue) AsInt32 () (int32,bool){
}
func (v CValue) AsInt64 () (int64,bool){
if v.vType != CValueTypeInt64 {
if v.vType != cValueTypeInt64 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -364,7 +370,7 @@ func (v CValue) AsInt64 () (int64,bool){
func (v CValue) AsUint () (uint,bool){
if v.vType != CValueTypeUint {
if v.vType != cValueTypeUint {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -377,7 +383,7 @@ func (v CValue) AsUint () (uint,bool){
}
func (v CValue) AsUint8 () (uint8,bool){
if v.vType != CValueTypeUint8 {
if v.vType != cValueTypeUint8 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -390,7 +396,7 @@ func (v CValue) AsUint8 () (uint8,bool){
}
func (v CValue) AsUint16 () (uint16,bool){
if v.vType != CValueTypeUint16 {
if v.vType != cValueTypeUint16 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -403,7 +409,7 @@ func (v CValue) AsUint16 () (uint16,bool){
}
func (v CValue) AsUint32 () (uint32,bool){
if v.vType != CValueTypeUint32 {
if v.vType != cValueTypeUint32 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -416,7 +422,7 @@ func (v CValue) AsUint32 () (uint32,bool){
}
func (v CValue) AsUint64 () (uint64,bool){
if v.vType != CValueTypeUint64 {
if v.vType != cValueTypeUint64 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -430,7 +436,7 @@ func (v CValue) AsUint64 () (uint64,bool){
func (v CValue) AsUintptr() (uintptr,bool){
if v.vType != CValueTypeUintptr {
if v.vType != cValueTypeUintptr {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -444,7 +450,7 @@ func (v CValue) AsUintptr() (uintptr,bool){
func (v CValue) AsFloat32() (float32,bool){
if v.vType != CValueTypeFloat32 {
if v.vType != cValueTypeFloat32 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -457,7 +463,7 @@ func (v CValue) AsFloat32() (float32,bool){
}
func (v CValue) AsFloat64() (float64,bool){
if v.vType != CValueTypeFloat64 {
if v.vType != cValueTypeFloat64 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -470,7 +476,7 @@ func (v CValue) AsFloat64() (float64,bool){
}
func (v CValue) AsComplex64 () (complex64,bool){
if v.vType != CValueTypeComplex64 {
if v.vType != cValueTypeComplex64 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -483,7 +489,7 @@ func (v CValue) AsComplex64 () (complex64,bool){
}
func (v CValue) AsComplex128() (complex128,bool){
if v.vType != CValueTypeComplex128 {
if v.vType != cValueTypeComplex128 {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -498,7 +504,7 @@ func (v CValue) AsComplex128() (complex128,bool){
func (v CValue) AsDuration() (Duration,bool){
if v.vType != CValueTypeDuration {
if v.vType != cValueTypeDuration {
return 0,false
}
if v.vState.HasNilOrZero() {
@ -511,7 +517,7 @@ func (v CValue) AsDuration() (Duration,bool){
}
func (v CValue) AsDate () (Date,bool){
if v.vType != CValueTypeDate {
if v.vType != cValueTypeDate {
return time.Time{},false
}
if v.vState.HasNilOrZero() {
@ -520,7 +526,7 @@ func (v CValue) AsDate () (Date,bool){
if v.vType.IsDefer() {
return (v.anyVal.(func()Date))(),true
}
if v.vState.HasValueShort() {
if v.vState.HasShort() {
// version corta del date
return time.Unix(0, v.intVal).In(v.anyVal.(*time.Location)), true
}
@ -529,7 +535,7 @@ func (v CValue) AsDate () (Date,bool){
func (v CValue) AsString () (string,bool){
if v.vType != CValueTypeString {
if v.vType != cValueTypeString {
return "", false
}
if v.vState.HasNilOrZero() {
@ -542,10 +548,10 @@ func (v CValue) AsString () (string,bool){
}
func (v CValue) AsStrings () ([]string,bool){
if v.vType != CValueTypeList|CValueTypeString {
if v.vType != cValueTypeList|cValueTypeString {
return nil,false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return nil,true
}
return v.anyVal.([]string),true
@ -553,10 +559,10 @@ func (v CValue) AsStrings () ([]string,bool){
func (v CValue) AsBytes () ([]byte,bool){
if v.vType != CValueTypeBytes {
if v.vType != cValueTypeBytes {
return nil, false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return []byte(nil),true
}
if v.vType.IsDefer() {
@ -567,10 +573,10 @@ func (v CValue) AsBytes () ([]byte,bool){
func (v CValue) AsStack () (Stack,bool){
if v.vType != CValueTypeStack {
if v.vType != cValueTypeStack {
return nil, false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return Stack(nil),true
}
if v.vType.IsDefer() {
@ -580,25 +586,25 @@ func (v CValue) AsStack () (Stack,bool){
}
func (v CValue) AsBaleable() (blrs.Baleable,bool){
if v.vType != CValueTypeBaleable {
func (v CValue) AsPackable() (Packable,bool){
if v.vType != cValueTypePackable {
return nil, false
}
if v.vState.HasValueNil() {
return blrs.Baleable(nil),true
if v.vState.HasNil() {
return Packable(nil),true
}
if v.vType.IsDefer() {
return v.anyVal.(blrs.Baleable),true
return v.anyVal.(Packable),true
}
return v.anyVal.(blrs.Baleable),true
return v.anyVal.(Packable),true
}
func (v CValue) AsError () (error,bool){
if v.vType != CValueTypeError {
if v.vType != cValueTypeError {
return nil, false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return error(nil),true
}
if v.vType.IsDefer() {
@ -609,7 +615,7 @@ func (v CValue) AsError () (error,bool){
func (v CValue) AsCValue () (CValue,bool) {
if v.vType != CValueTypeCValue {
if v.vType != cValueTypeCValue {
return CValue{}, false
}
if v.vType.IsDefer() {
@ -619,7 +625,7 @@ func (v CValue) AsCValue () (CValue,bool) {
}
func (v CValue) AsCField () (CField,bool) {
if v.vType != CValueTypeCField {
if v.vType != cValueTypeCField {
return CField{}, false
}
if v.vType.IsDefer() {
@ -629,10 +635,10 @@ func (v CValue) AsCField () (CField,bool) {
}
func (v CValue) AsCFields() ([]CField,bool) {
if v.vType != CValueTypeCField|CValueTypeList {
if v.vType != cValueTypeCField|cValueTypeList {
return nil, false
}
if v.vState.HasValueNil() {
if v.vState.HasNil() {
return nil, false
}
if v.vType.IsDefer() {
@ -644,7 +650,7 @@ func (v CValue) AsCFields() ([]CField,bool) {
func (v CValue) AsObject () (any,bool) {
if v.vType != CValueTypeObject {
if v.vType != cValueTypeObject {
return nil, false
}
if v.vType.IsDefer() {
@ -654,7 +660,7 @@ func (v CValue) AsObject () (any,bool) {
}
func (v CValue) AsList () (any,bool) {
if v.vType != CValueTypeList {
if v.vType != cValueTypeList {
return nil, false
}
if v.vType.IsDefer() {
@ -664,7 +670,7 @@ func (v CValue) AsList () (any,bool) {
}
func (v CValue) AsMap () (any,bool) {
if v.vType != CValueTypeMap {
if v.vType != cValueTypeMap {
return nil, false
}
if v.vType.IsDefer() {
@ -672,3 +678,9 @@ func (v CValue) AsMap () (any,bool) {
}
return v.anyVal,true
}
func (v CValue) Pack (packer Packer) {
}

@ -51,16 +51,16 @@ const (
type CValueState uint8
func (s CValueState) HasValueInvalid () bool { return s&cValueStateInvalid != 0 }
func (s CValueState) HasValueNil () bool { return s&cValueStateNil != 0 }
func (s CValueState) HasValueZero () bool { return s&cValueStateZero != 0 }
func (s CValueState) HasValueReflected() bool { return s&cValueStateReflected != 0 }
func (s CValueState) HasValueShort () bool { return s&cValueStateShort != 0 }
func (s CValueState) HasValueSensitive() bool { return s&cValueStateSensitive != 0 }
func (s CValueState) HasValueEncoded () bool { return s&cValueStateEncoded != 0 }
func (s CValueState) HasValueError () bool { return s&cValueStateError != 0 }
func (s CValueState) HasInvalid () bool { return s&cValueStateInvalid != 0 }
func (s CValueState) HasNil () bool { return s&cValueStateNil != 0 }
func (s CValueState) HasZero () bool { return s&cValueStateZero != 0 }
func (s CValueState) HasReflected() bool { return s&cValueStateReflected != 0 }
func (s CValueState) HasShort () bool { return s&cValueStateShort != 0 }
func (s CValueState) HasSensitive() bool { return s&cValueStateSensitive != 0 }
func (s CValueState) HasEncoded () bool { return s&cValueStateEncoded != 0 }
func (s CValueState) HasError () bool { return s&cValueStateError != 0 }
func (s CValueState) HasNilOrZero () bool { return s&(cValueStateZero|cValueStateNil) != 0 }
func (s CValueState) HasNilOrZero() bool { return s&(cValueStateZero|cValueStateNil) != 0 }
func (s CValueState) setOption (options CValueState) CValueState { return s|(options&cValueStateOps) }

@ -38,55 +38,55 @@ const (
maxCValueTypes int = 32
// CValueType's definidos
CValueTypeInvalid CValueType = 0
cValueTypeInvalid CValueType = 0
CValueTypeAny CValueType = 1 << 0
CValueTypeBool CValueType = 1 << 1
cValueTypeAny CValueType = 1 << 0
cValueTypeBool CValueType = 1 << 1
CValueTypeInt CValueType = 1 << 2
CValueTypeInt8 CValueType = 1 << 3
CValueTypeInt16 CValueType = 1 << 4
CValueTypeInt32 CValueType = 1 << 5
CValueTypeInt64 CValueType = 1 << 6
cValueTypeInt CValueType = 1 << 2
cValueTypeInt8 CValueType = 1 << 3
cValueTypeInt16 CValueType = 1 << 4
cValueTypeInt32 CValueType = 1 << 5
cValueTypeInt64 CValueType = 1 << 6
CValueTypeUint CValueType = 1 << 7
CValueTypeUint8 CValueType = 1 << 8
CValueTypeUint16 CValueType = 1 << 9
CValueTypeUint32 CValueType = 1 << 10
CValueTypeUint64 CValueType = 1 << 11
cValueTypeUint CValueType = 1 << 7
cValueTypeUint8 CValueType = 1 << 8
cValueTypeUint16 CValueType = 1 << 9
cValueTypeUint32 CValueType = 1 << 10
cValueTypeUint64 CValueType = 1 << 11
CValueTypeUintptr CValueType = 1 << 12
cValueTypeUintptr CValueType = 1 << 12
CValueTypeFloat32 CValueType = 1 << 13
CValueTypeFloat64 CValueType = 1 << 14
cValueTypeFloat32 CValueType = 1 << 13
cValueTypeFloat64 CValueType = 1 << 14
CValueTypeComplex64 CValueType = 1 << 15
CValueTypeComplex128 CValueType = 1 << 16
cValueTypeComplex64 CValueType = 1 << 15
cValueTypeComplex128 CValueType = 1 << 16
CValueTypeDuration CValueType = 1 << 17
CValueTypeDate CValueType = 1 << 18
cValueTypeDuration CValueType = 1 << 17
cValueTypeDate CValueType = 1 << 18
CValueTypeString CValueType = 1 << 19
CValueTypeBytes CValueType = 1 << 20
CValueTypeStack CValueType = 1 << 21
cValueTypeString CValueType = 1 << 19
cValueTypeBytes CValueType = 1 << 20
cValueTypeStack CValueType = 1 << 21
CValueTypeBaleable CValueType = 1 << 22
CValueTypeError CValueType = 1 << 23
cValueTypePackable CValueType = 1 << 22
cValueTypeError CValueType = 1 << 23
CValueTypeNil CValueType = 1 << 24
cValueTypeNil CValueType = 1 << 24
CValueTypeCValue CValueType = 1 << 25
CValueTypeCField CValueType = 1 << 26
CValueTypeObject CValueType = 1 << 27
cValueTypeCValue CValueType = 1 << 25
cValueTypeCField CValueType = 1 << 26
cValueTypeObject CValueType = 1 << 27
CValueTypeDefer CValueType = 1 << 28
CValueTypeList CValueType = 1 << 29
CValueTypeMap CValueType = 1 << 30
CValueTypeMapKey CValueType = 1 << 31
cValueTypeDefer CValueType = 1 << 28
cValueTypeList CValueType = 1 << 29
cValueTypeMap CValueType = 1 << 30
cValueTypeMapKey CValueType = 1 << 31
maskCValueTypeComposite= CValueTypeDefer|CValueTypeList|CValueTypeMap
maskCValueTypeBase = ^(maskCValueTypeComposite | CValueTypeMapKey)
maskCValueTypeComposite= cValueTypeDefer | cValueTypeList | cValueTypeMap
maskCValueTypeBase = ^(maskCValueTypeComposite | cValueTypeMapKey)
)
@ -99,64 +99,64 @@ type (
func (t CValueType) IsComposite() bool { return t&maskCValueTypeComposite != 0 }
func (t CValueType) BaseType () CValueType {
if t&CValueTypeMap == 0 {
if t&cValueTypeMap == 0 {
return t &maskCValueTypeBase
}
_,vt := t.MapType()
return vt
}
func (t CValueType) MapType () (CValueType,CValueType) {
if t&CValueTypeMap == 0 {
return CValueTypeInvalid, CValueTypeInvalid
func (t CValueType) MapType () (CValueType, CValueType) {
if t&cValueTypeMap == 0 {
return cValueTypeInvalid, cValueTypeInvalid
}
bs := t &maskCValueTypeBase
switch bits.OnesCount32(uint32(bs)) {
case 1: return bs,bs
case 2:
if t&CValueTypeMapKey == 0 {
if t&cValueTypeMapKey == 0 {
return bs&-bs,bs&^(bs&-bs)
}
return bs&^(bs&-bs),bs&-bs
default:
return CValueTypeInvalid,CValueTypeInvalid
return cValueTypeInvalid, cValueTypeInvalid
}
}
func (t CValueType) IsTypeInvalid () bool { return t&maskCValueTypeBase == CValueTypeInvalid }
func (t CValueType) IsTypeAny () bool { return t&maskCValueTypeBase == CValueTypeAny }
func (t CValueType) IsTypeBool () bool { return t&maskCValueTypeBase == CValueTypeBool }
func (t CValueType) IsTypeInt () bool { return t&maskCValueTypeBase == CValueTypeInt }
func (t CValueType) IsTypeInt8 () bool { return t&maskCValueTypeBase == CValueTypeInt8 }
func (t CValueType) IsTypeInt16 () bool { return t&maskCValueTypeBase == CValueTypeInt16 }
func (t CValueType) IsTypeInt32 () bool { return t&maskCValueTypeBase == CValueTypeInt32 }
func (t CValueType) IsTypeInt64 () bool { return t&maskCValueTypeBase == CValueTypeInt64 }
func (t CValueType) IsTypeUint () bool { return t&maskCValueTypeBase == CValueTypeUint }
func (t CValueType) IsTypeUint8 () bool { return t&maskCValueTypeBase == CValueTypeUint8 }
func (t CValueType) IsTypeUint16 () bool { return t&maskCValueTypeBase == CValueTypeUint16 }
func (t CValueType) IsTypeUint32 () bool { return t&maskCValueTypeBase == CValueTypeUint32 }
func (t CValueType) IsTypeUint64 () bool { return t&maskCValueTypeBase == CValueTypeUint64 }
func (t CValueType) IsTypeUintptr () bool { return t&maskCValueTypeBase == CValueTypeUintptr }
func (t CValueType) IsTypeFloat32 () bool { return t&maskCValueTypeBase == CValueTypeFloat32 }
func (t CValueType) IsTypeFloat64 () bool { return t&maskCValueTypeBase == CValueTypeFloat64 }
func (t CValueType) IsTypeComplex64 () bool { return t&maskCValueTypeBase == CValueTypeComplex64}
func (t CValueType) IsTypeComplex128 () bool { return t&maskCValueTypeBase == CValueTypeComplex128}
func (t CValueType) IsTypeDuration () bool { return t&maskCValueTypeBase == CValueTypeDuration }
func (t CValueType) IsTypeDate () bool { return t&maskCValueTypeBase == CValueTypeDate }
func (t CValueType) IsTypeString () bool { return t&maskCValueTypeBase == CValueTypeString }
func (t CValueType) IsTypeBytes () bool { return t&maskCValueTypeBase == CValueTypeBytes }
func (t CValueType) IsTypeStack () bool { return t&maskCValueTypeBase == CValueTypeStack }
func (t CValueType) IsTypeBaleable () bool { return t&maskCValueTypeBase == CValueTypeBaleable }
func (t CValueType) IsTypeError () bool { return t&maskCValueTypeBase == CValueTypeError }
func (t CValueType) IsTypeNil () bool { return t&maskCValueTypeBase == CValueTypeNil }
func (t CValueType) IsTypeCVal () bool { return t&maskCValueTypeBase == CValueTypeCValue }
func (t CValueType) IsTypeCField () bool { return t&maskCValueTypeBase == CValueTypeCField }
func (t CValueType) IsTypeObject () bool { return t&maskCValueTypeBase == CValueTypeObject }
func (t CValueType) IsDefer () bool { return t&CValueTypeDefer != 0 }
func (t CValueType) IsList () bool { return t&CValueTypeList != 0 }
func (t CValueType) IsMap () bool { return t&CValueTypeMap != 0 }
func (t CValueType) IsInvalid() bool { return t&maskCValueTypeBase == cValueTypeInvalid }
func (t CValueType) IsAny() bool { return t&maskCValueTypeBase == cValueTypeAny }
func (t CValueType) IsBool() bool { return t&maskCValueTypeBase == cValueTypeBool }
func (t CValueType) IsInt() bool { return t&maskCValueTypeBase == cValueTypeInt }
func (t CValueType) IsInt8() bool { return t&maskCValueTypeBase == cValueTypeInt8 }
func (t CValueType) IsInt16() bool { return t&maskCValueTypeBase == cValueTypeInt16 }
func (t CValueType) IsInt32() bool { return t&maskCValueTypeBase == cValueTypeInt32 }
func (t CValueType) IsInt64() bool { return t&maskCValueTypeBase == cValueTypeInt64 }
func (t CValueType) IsUint() bool { return t&maskCValueTypeBase == cValueTypeUint }
func (t CValueType) IsUint8() bool { return t&maskCValueTypeBase == cValueTypeUint8 }
func (t CValueType) IsUint16() bool { return t&maskCValueTypeBase == cValueTypeUint16 }
func (t CValueType) IsUint32() bool { return t&maskCValueTypeBase == cValueTypeUint32 }
func (t CValueType) IsUint64() bool { return t&maskCValueTypeBase == cValueTypeUint64 }
func (t CValueType) IsUintptr() bool { return t&maskCValueTypeBase == cValueTypeUintptr }
func (t CValueType) IsFloat32() bool { return t&maskCValueTypeBase == cValueTypeFloat32 }
func (t CValueType) IsFloat64() bool { return t&maskCValueTypeBase == cValueTypeFloat64 }
func (t CValueType) IsComplex64 () bool { return t&maskCValueTypeBase == cValueTypeComplex64 }
func (t CValueType) IsComplex128() bool { return t&maskCValueTypeBase == cValueTypeComplex128 }
func (t CValueType) IsDuration()bool { return t&maskCValueTypeBase == cValueTypeDuration }
func (t CValueType) IsDate() bool { return t&maskCValueTypeBase == cValueTypeDate }
func (t CValueType) IsString() bool { return t&maskCValueTypeBase == cValueTypeString }
func (t CValueType) IsBytes() bool { return t&maskCValueTypeBase == cValueTypeBytes }
func (t CValueType) IsStack() bool { return t&maskCValueTypeBase == cValueTypeStack }
func (t CValueType) IsBaleable()bool { return t&maskCValueTypeBase == cValueTypePackable }
func (t CValueType) IsError() bool { return t&maskCValueTypeBase == cValueTypeError }
func (t CValueType) IsNil() bool { return t&maskCValueTypeBase == cValueTypeNil }
func (t CValueType) IsCValue() bool { return t&maskCValueTypeBase == cValueTypeCValue }
func (t CValueType) IsCField() bool { return t&maskCValueTypeBase == cValueTypeCField }
func (t CValueType) IsObject() bool { return t&maskCValueTypeBase == cValueTypeObject }
func (t CValueType) IsDefer () bool { return t&cValueTypeDefer != 0 }
func (t CValueType) IsList () bool { return t&cValueTypeList != 0 }
func (t CValueType) IsMap () bool { return t&cValueTypeMap != 0 }
func (t CValueType) String () string {
@ -165,16 +165,16 @@ func (t CValueType) String () string {
func buildMapType(keyType, valType CValueType) CValueType {
if keyType == CValueTypeInvalid || valType == CValueTypeInvalid {
return CValueTypeInvalid
if keyType == cValueTypeInvalid || valType == cValueTypeInvalid {
return cValueTypeInvalid
}
if keyType == valType {
return CValueTypeMap|keyType
return cValueTypeMap |keyType
}
if keyType < valType {
return CValueTypeMap|keyType|valType
return cValueTypeMap |keyType|valType
}
return CValueTypeMap|valType|keyType|CValueTypeMapKey
return cValueTypeMap |valType|keyType| cValueTypeMapKey
}

@ -29,11 +29,9 @@
package vals
import (
"math"
"math/bits"
"reflect"
"sync"
"time"
)
const(
@ -52,8 +50,6 @@ type (
mux sync.RWMutex
names [maxCValueTypes+1]string
creators [maxCValueTypes+1][cValueNumCreators]func(any)CValue
minTime,
maxTime time.Time
cache map[reflect.Type]func(value any)CValue
}
)
@ -61,8 +57,7 @@ type (
func newCValueTypeInfos () *CValueTypeInfos {
is := CValueTypeInfos{
minTime : time.Unix(0, math.MinInt64),
maxTime : time.Unix(0, math.MaxInt64),
cache : make(map[reflect.Type]func(value any)CValue),
names : [maxCValueTypes+1]string{
/* 0: */ "invalid",
@ -100,51 +95,51 @@ func newCValueTypeInfos () *CValueTypeInfos {
/* 32: */ "flag",
},
creators: [maxCValueTypes+1][cValueNumCreators]func(any)CValue{
/* 0: */ createGValCreators[any ](CValueTypeInvalid,createCValueInvalid),
/* 1: */ createGValCreators[any ](CValueTypeAny, createCValueAny),
/* 2: */ createGValCreators[bool ](CValueTypeBool, CreateCValueBool),
/* 3: */ createGValCreators[int ](CValueTypeInt, CreateCValueInt),
/* 4: */ createGValCreators[int8 ](CValueTypeInt8, CreateCValueInt8),
/* 5: */ createGValCreators[int16 ](CValueTypeInt16, CreateCValueInt16),
/* 6: */ createGValCreators[int32 ](CValueTypeInt32, CreateCValueInt32),
/* 7: */ createGValCreators[int64 ](CValueTypeInt64, CreateCValueInt64),
/* 8: */ createGValCreators[uint ](CValueTypeUint, CreateCValueUint),
/* 0: */ createGValCreators[any ](cValueTypeInvalid,createCValueInvalid),
/* 1: */ createGValCreators[any ](cValueTypeAny, createCValueAny),
/* 2: */ createGValCreators[bool ](cValueTypeBool, CreateCValueBool),
/* 3: */ createGValCreators[int ](cValueTypeInt, CreateCValueInt),
/* 4: */ createGValCreators[int8 ](cValueTypeInt8, CreateCValueInt8),
/* 5: */ createGValCreators[int16 ](cValueTypeInt16, CreateCValueInt16),
/* 6: */ createGValCreators[int32 ](cValueTypeInt32, CreateCValueInt32),
/* 7: */ createGValCreators[int64 ](cValueTypeInt64, CreateCValueInt64),
/* 8: */ createGValCreators[uint ](cValueTypeUint, CreateCValueUint),
/*
caso en el que []uint debe de establecerse como bytes procedemos a construirlo manualmente
*/
/* 9 :*/ {
func(v any) CValue { return CreateCValueUint8 (v.(uint8)) },
func(v any) CValue { return createGValTypePointer(CValueTypeUint8, CreateCValueUint8, v.(*uint8)) },
func(v any) CValue { return createGValTypeList (CValueTypeBytes, v.([]uint8)) },
func(v any) CValue { return createGValTypeDefer (CValueTypeDefer|CValueTypeUint8, v.(func() uint8))},
func(v any) CValue { return createGValTypePointer(cValueTypeUint8, CreateCValueUint8, v.(*uint8)) },
func(v any) CValue { return createGValTypeList (cValueTypeBytes, v.([]uint8)) },
func(v any) CValue { return createGValTypeDefer (cValueTypeDefer|cValueTypeUint8, v.(func() uint8))},
},
/* 10:*/ createGValCreators[uint16 ](CValueTypeUint16, CreateCValueUint16),
/* 11:*/ createGValCreators[uint32 ](CValueTypeUint32, CreateCValueUint32),
/* 12:*/ createGValCreators[uint64 ](CValueTypeUint64, CreateCValueUint64),
/* 13:*/ createGValCreators[uintptr ](CValueTypeUintptr, CreateCValueUintptr),
/* 14:*/ createGValCreators[float32 ](CValueTypeFloat32, CreateCValueFloat32),
/* 15:*/ createGValCreators[float64 ](CValueTypeFloat64, CreateCValueFloat64),
/* 16:*/ createGValCreators[complex64 ](CValueTypeComplex64, CreateCValueComplex64),
/* 17:*/ createGValCreators[complex128 ](CValueTypeComplex128, CreateCValueComplex128),
/* 18:*/ createGValCreators[Duration ](CValueTypeDuration, CreateCValueDuration),
/* 19:*/ createGValCreators[Date ](CValueTypeDate, CreateCValueDate),
/* 20:*/ createGValCreators[string ](CValueTypeString, CreateCValueString),
/* 21:*/ createGValCreators[Bytes ](CValueTypeBytes, CreateCValueBytes),
/* 22:*/ createGValCreators[Stack ](CValueTypeStack, CreateCValueStack),
/* 23:*/ createGValCreators[Baleable ](CValueTypeBaleable, CreateCValueBaleable),
/* 24:*/ createGValCreators[error ](CValueTypeError, CreateCValueError),
/* 25:*/ createGValCreators[any ](CValueTypeNil, CreateCValueNil),
/* 26:*/ createGValCreators[CValue ](CValueTypeCValue, createCValueCValue),
/* 27:*/ createGValCreators[CField ](CValueTypeCField, createCValueCField),
/* 28:*/ createGValCreators[any ](CValueTypeObject, createCValueObject),
/* 29:*/ createGValCreators[any ](CValueTypeDefer, CreateCValueDefer),
/* 30:*/ createGValCreators[any ](CValueTypeList, CreateCValueList),
/* 31:*/ createGValCreators[any ](CValueTypeMap, CreateCValueMap),
/* 32:*/ createGValCreators[any ](CValueTypeObject, createCValueInvalid),
/* 10:*/ createGValCreators[uint16 ](cValueTypeUint16, CreateCValueUint16),
/* 11:*/ createGValCreators[uint32 ](cValueTypeUint32, CreateCValueUint32),
/* 12:*/ createGValCreators[uint64 ](cValueTypeUint64, CreateCValueUint64),
/* 13:*/ createGValCreators[uintptr ](cValueTypeUintptr, CreateCValueUintptr),
/* 14:*/ createGValCreators[float32 ](cValueTypeFloat32, CreateCValueFloat32),
/* 15:*/ createGValCreators[float64 ](cValueTypeFloat64, CreateCValueFloat64),
/* 16:*/ createGValCreators[complex64 ](cValueTypeComplex64, CreateCValueComplex64),
/* 17:*/ createGValCreators[complex128 ](cValueTypeComplex128, CreateCValueComplex128),
/* 18:*/ createGValCreators[Duration ](cValueTypeDuration, CreateCValueDuration),
/* 19:*/ createGValCreators[Date ](cValueTypeDate, CreateCValueDate),
/* 20:*/ createGValCreators[string ](cValueTypeString, CreateCValueString),
/* 21:*/ createGValCreators[Bytes ](cValueTypeBytes, CreateCValueBytes),
/* 22:*/ createGValCreators[Stack ](cValueTypeStack, CreateCValueStack),
/* 23:*/ createGValCreators[Packable](cValueTypePackable, CreateCValueBaleable),
/* 24:*/ createGValCreators[error ](cValueTypeError, CreateCValueError),
/* 25:*/ createGValCreators[any ](cValueTypeNil, CreateCValueNil),
/* 26:*/ createGValCreators[CValue ](cValueTypeCValue, createCValueCValue),
/* 27:*/ createGValCreators[CField ](cValueTypeCField, createCValueCField),
/* 28:*/ createGValCreators[any ](cValueTypeObject, createCValueObject),
/* 29:*/ createGValCreators[any ](cValueTypeDefer, CreateCValueDefer),
/* 30:*/ createGValCreators[any ](cValueTypeList, CreateCValueList),
/* 31:*/ createGValCreators[any ](cValueTypeMap, CreateCValueMap),
/* 32:*/ createGValCreators[any ](cValueTypeObject, createCValueInvalid),
},
}
return &is
@ -201,7 +196,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
case string : f = i.creators[20/* String */][cValueByVal]
case Bytes : f = i.creators[21/* Bytes */][cValueByVal]
case Stack : f = i.creators[22/* Stack */][cValueByVal]
case Baleable : f = i.creators[23/* Baleable */][cValueByVal]
case Packable: f = i.creators[23 /* Packable */][cValueByVal]
case error : f = i.creators[24/* Error */][cValueByVal]
case CValue : f = i.creators[26/* CVal */][cValueByVal]
case CField : f = i.creators[27/* CCField */][cValueByVal]
@ -216,7 +211,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
case []int64 : f = i.creators[ 7/* Int64 */][cValueByLst]
case []uint : f = i.creators[ 8/* Uint */][cValueByLst]
// ya establecido como tipo base Bytes
//case []uint8 : f = i.creators[ 9/* CValueTypeUint8 */].listCreator
//case []uint8 : f = i.creators[ 9/* cValueTypeUint8 */].listCreator
//
case []uint16 : f = i.creators[10/* Uint16 */][cValueByLst]
case []uint32 : f = i.creators[11/* Uint32 */][cValueByLst]
@ -231,7 +226,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
case []string : f = i.creators[20/* String */][cValueByLst]
case []Bytes : f = i.creators[21/* String */][cValueByLst]
case []Stack : f = i.creators[22/* Stack */][cValueByLst]
case []Baleable : f = i.creators[23/* Baleable */][cValueByLst]
case []Packable: f = i.creators[23 /* Packable */][cValueByLst]
case []error : f = i.creators[24/* Error */][cValueByLst]
case []CValue : f = i.creators[26/* CValue */][cValueByLst]
case []CField : f = i.creators[27/* CField */][cValueByLst]
@ -259,7 +254,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
case *string : f = i.creators[20/* String */][cValueByPtr]
case *Bytes : f = i.creators[21/* Bytes */][cValueByPtr]
case *Stack : f = i.creators[22/* Stack */][cValueByPtr]
case *Baleable : f = i.creators[23/* Baleable */][cValueByPtr]
case *Packable: f = i.creators[23 /* Packable */][cValueByPtr]
case *error : f = i.creators[24/* Error */][cValueByPtr]
case *CValue : f = i.creators[26/* CValue */][cValueByPtr]
case *CField : f = i.creators[27/* CField */][cValueByPtr]
@ -287,7 +282,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
case func()string : f = i.creators[20/* String */][cValueByDfr]
case func()Bytes : f = i.creators[21/* Bytes */][cValueByDfr]
case func()Stack : f = i.creators[22/* Stack */][cValueByDfr]
case func()Baleable : f = i.creators[23/* Baleable */][cValueByDfr]
case func() Packable: f = i.creators[23 /* Packable */][cValueByDfr]
case func()error : f = i.creators[24/* Error */][cValueByDfr]
case func()CValue : f = i.creators[26/* CVal */][cValueByDfr]
case func()CField : f = i.creators[27/* CField */][cValueByDfr]
@ -305,7 +300,7 @@ func (i *CValueTypeInfos) CreateCValue(value any) CValue {
func (i *CValueTypeInfos) createByReflection(value any) CValue {
rv := reflect.ValueOf(value)
if !rv.IsValid() {
return createCValueWithInvalidError(value,CValueTypeAny,0,E.InvalidCValueReflected)
return createCValueWithInvalidError(value, cValueTypeAny,0,E.InvalidCValueReflected)
}
rt := rv.Type()
@ -317,23 +312,23 @@ func (i *CValueTypeInfos) createByReflection(value any) CValue {
}
i.mux.RUnlock()
vt := CValueTypeAny
vt := cValueTypeAny
switch rt.Kind() {
// Los tipos soportados deben de haber sido capturados
// por el switch de tipos
case reflect.Struct : // createCValueAny
vt = CValueTypeObject
vt = cValueTypeObject
case reflect.Func :
if rt.NumIn() == 0 && rt.NumOut() == 1 {
vt = CValueTypeDefer|CValueTypeAny
vt = cValueTypeDefer | cValueTypeAny
}
case reflect.Map :
var kt,et CValueType
if kt = reflectKindToCValueType(rt.Key().Kind(),true); kt != CValueTypeInvalid {
if et = reflectKindToCValueType(rt.Elem().Kind(),true); et != CValueTypeInvalid {
if kt = reflectKindToCValueType(rt.Key().Kind(),true); kt != cValueTypeInvalid {
if et = reflectKindToCValueType(rt.Elem().Kind(),true); et != cValueTypeInvalid {
vt = buildMapType(kt,et)
}
}
@ -341,12 +336,12 @@ func (i *CValueTypeInfos) createByReflection(value any) CValue {
case reflect.Slice,
reflect.Array :
ke := reflectKindToCValueType(rt.Elem().Kind(),true)
if ke != CValueTypeInvalid {
vt = ke|CValueTypeList
if ke != cValueTypeInvalid {
vt = ke| cValueTypeList
}
case reflect.Interface:
vt = CValueTypeAny
vt = cValueTypeAny
}
f = func(v any) CValue {
@ -383,7 +378,7 @@ func createCValueReflected (value any, rv reflect.Value, vtype CValueType, check
return createCValueWithInvalidError(value,vtype,vs,E.InvalidCValueForType)
}
ke := reflectKindToCValueType(rt.Elem().Kind(), true)
if ke == CValueTypeInvalid {
if ke == cValueTypeInvalid {
return createCValueWithInvalidError(value,vtype,vs,E.InvalidCValueForType)
}
vtype |= ke
@ -405,11 +400,11 @@ func createCValueReflected (value any, rv reflect.Value, vtype CValueType, check
return createCValueWithInvalidError(value,vtype,vs|cValueStateInvalid,E.InvalidCValueForType)
}
kt := reflectKindToCValueType(rt.Key().Kind(), true)
if kt == CValueTypeInvalid {
if kt == cValueTypeInvalid {
return createCValueWithInvalidError(value,vtype,vs|cValueStateInvalid,E.InvalidCValueForType)
}
et := reflectKindToCValueType(rt.Elem().Kind(), true)
if et == CValueTypeInvalid {
if et == cValueTypeInvalid {
return createCValueWithInvalidError(value,vtype,vs|cValueStateInvalid,E.InvalidCValueForType)
}
vtype = buildMapType(kt, et)
@ -433,7 +428,7 @@ func createCValueReflected (value any, rv reflect.Value, vtype CValueType, check
if rt.NumIn() != 0 || rt.NumOut() != 1 {
return createCValueWithInvalidError(value,vtype,vs,E.InvalidCValueForType)
}
vtype = CValueTypeDefer|CValueTypeAny
vtype = cValueTypeDefer | cValueTypeAny
}
if rv.IsNil() {
vs|=cValueStateNil
@ -446,7 +441,7 @@ func createCValueReflected (value any, rv reflect.Value, vtype CValueType, check
case reflect.Struct :
if check {
if !vtype.IsTypeObject() {
if !vtype.IsObject() {
return createCValueWithInvalidError(value,vtype,vs,E.InvalidCValueForType)
}
}
@ -473,8 +468,8 @@ func createGValCreators [T any] (valType CValueType, createFnc func(value T) CVa
return [cValueNumCreators]func(any)CValue {
func(v any) CValue { return createFnc(v.(T)) },
func(v any) CValue { return createGValTypePointer(valType,createFnc,v.(*T))},
func(v any) CValue { return createGValTypeList (CValueTypeList |valType,v.([]T)) },
func(v any) CValue { return createGValTypeDefer (CValueTypeDefer|valType,v.(func() T)) },
func(v any) CValue { return createGValTypeList (cValueTypeList|valType,v.([]T)) },
func(v any) CValue { return createGValTypeDefer (cValueTypeDefer|valType,v.(func() T)) },
}
}
@ -506,7 +501,7 @@ func createGValTypeDefer[T any](vType CValueType,value func()T) CValue {
func buildCValueInvalidWithError (err string) func(v any) CValue {
return func(v any) CValue {
return CValue{vType: CValueTypeInvalid, vState: cValueStateInvalid|cValueStateError, anyVal: v, strVal: err }
return CValue{vType: cValueTypeInvalid, vState: cValueStateInvalid|cValueStateError, anyVal: v, strVal: err }
}
}
@ -515,40 +510,40 @@ func buildCValueInvalidWithError (err string) func(v any) CValue {
func reflectKindToCValueType (kind reflect.Kind, base bool) CValueType {
switch kind {
case reflect.Invalid: return CValueTypeInvalid
case reflect.Bool: return CValueTypeBool
case reflect.Int: return CValueTypeInt
case reflect.Int8: return CValueTypeInt8
case reflect.Int16: return CValueTypeInt16
case reflect.Int32: return CValueTypeInt32
case reflect.Int64: return CValueTypeInt64
case reflect.Uint: return CValueTypeUint
case reflect.Uint8: return CValueTypeUint8
case reflect.Uint16: return CValueTypeUint16
case reflect.Uint32: return CValueTypeUint32
case reflect.Uint64: return CValueTypeUint64
case reflect.Uintptr: return CValueTypeUintptr
case reflect.Float32: return CValueTypeFloat32
case reflect.Float64: return CValueTypeFloat64
case reflect.Complex64: return CValueTypeComplex64
case reflect.Complex128:return CValueTypeComplex128
case reflect.String: return CValueTypeString
case reflect.Struct: return CValueTypeObject
case reflect.Invalid: return cValueTypeInvalid
case reflect.Bool: return cValueTypeBool
case reflect.Int: return cValueTypeInt
case reflect.Int8: return cValueTypeInt8
case reflect.Int16: return cValueTypeInt16
case reflect.Int32: return cValueTypeInt32
case reflect.Int64: return cValueTypeInt64
case reflect.Uint: return cValueTypeUint
case reflect.Uint8: return cValueTypeUint8
case reflect.Uint16: return cValueTypeUint16
case reflect.Uint32: return cValueTypeUint32
case reflect.Uint64: return cValueTypeUint64
case reflect.Uintptr: return cValueTypeUintptr
case reflect.Float32: return cValueTypeFloat32
case reflect.Float64: return cValueTypeFloat64
case reflect.Complex64: return cValueTypeComplex64
case reflect.Complex128:return cValueTypeComplex128
case reflect.String: return cValueTypeString
case reflect.Struct: return cValueTypeObject
case reflect.Array,
reflect.Slice:
if base {
return CValueTypeList
return cValueTypeList
}
return CValueTypeAny
return cValueTypeAny
case reflect.Map:
if base {
return CValueTypeMap
return cValueTypeMap
}
return CValueTypeAny
return cValueTypeAny
default:
return CValueTypeAny
return cValueTypeAny
}
}

@ -29,8 +29,8 @@
package vals
import (
"core/blrs"
"core/excs"
"core/pkrs"
"time"
)
@ -41,7 +41,8 @@ type (
Date = time.Time
Duration = time.Duration
Stack = excs.Stack
Baleable = blrs.Baleable
Packer = pkrs.Packer
Packable = pkrs.Packable
)

Loading…
Cancel
Save

Powered by TurnKey Linux.