cdts creado, refinando ctype y cvalue

master
dev 1 year ago
parent aed26728b3
commit 4a43e5b278

@ -29,43 +29,18 @@
package main
import (
"base/cdts"
"corx/cdts"
"fmt"
)
func main() {
/*
var m map[string]int = map[string]int{ "ss" : 22, "ds" : 434}
c := vals.G.TypeInfos.CreateCValue(m)
fmt.Printf("%v+ --> %s \n",c,c.Type().String())
g := vals.G.TypeInfos.CreateCValue(func() int { return 1 } )
fmt.Printf("%v+ --> %s \n",g,g.Type().String())
var f func() int
g = vals.G.TypeInfos.CreateCValue(f)
fmt.Printf("%v+ --> %s %s \n",g,g.Type().String(),g.State().String())
type st struct { na string }
var a *st
e := vals.G.TypeInfos.CreateCValue(a)
fmt.Printf("%v+ --> %s %s \n",e,e.Type().String(),e.State().String())
*/
var an any
type s struct { m string }
an = []s { { m: "dfdff"}, {m: "aaaa"} }
e := cdts.CreateCValue(an)
fmt.Printf("%v+ --> tipo : %s estado :%s \n",e,e.Type().String(),e.State().String())
m := map[string]int {"dd":3,"d":3,}
d := func() int { return 3}
cv := cdts.G.CTypes.CreateByReflection(m,cdts.CreateCVTypeMap(cdts.CBTypeAny,cdts.CBTypeAny))
fmt.Printf ("CValue %v\n", cv)
cv = cdts.G.CTypes.CreateByReflection(d,cdts.CreateCVTypeLazy(cdts.CBTypeAny))
fmt.Printf ("CValue %v\n", cv)
}

@ -71,6 +71,12 @@ type (
var (
G = struct {
CTypes *cBTypeInfos
} {
CTypes: newCBTypeInfos(),
}
g = struct {
bigZero *BigInt
@ -91,9 +97,10 @@ var (
}
E = struct {
InvalidReflectValue string
UnexpectedTypeReflected,
InvalidReflectValue string
}{
InvalidReflectValue: "::invalid_reflect_value",
UnexpectedTypeReflected : "::unexpected_type_reflected",
InvalidReflectValue : "::invalid_reflect_value",
}
)

@ -68,6 +68,7 @@ const (
CBTypeDate
CBTypeCValue
CBTypeReflect
CBTypeObject
CBTypeListPackable

@ -45,31 +45,34 @@ type (
func newCBTypeInfos() *cBTypeInfos {
vi := &cBTypeInfos{}
vi := &cBTypeInfos{
cache : make(map[reflect.Type]func(reflect.Value) CValue),
}
vi.types = []*cBTypeInfo{
/* 01 */ newCVTypeInfo(CBTypeInvalid ,"invalid" , optInvalidCreators()),
/* 02 */ newCVTypeInfo(CBTypeAny ,"any" , optAnyCreators [any ](nil)),
/* 03 */ newCVTypeInfo(CBTypeBool ,"bool" , optNormalCreators [bool ](CreateCBool)),
/* 04 */ newCVTypeInfo(CBTypeInt ,"int" , optNormalCreators [int ](CreateCInt)),
/* 05 */ newCVTypeInfo(CBTypeInt8 ,"int8" , optNormalCreators [int8 ](CreateCInt8)),
/* 06 */ newCVTypeInfo(CBTypeInt16 ,"int16" , optNormalCreators [int16 ](CreateCInt16)),
/* 07 */ newCVTypeInfo(CBTypeInt64 ,"int64" , optNormalCreators [int64 ](CreateCInt64)),
/* 08 */ newCVTypeInfo(CBTypeUint ,"uint" , optNormalCreators [uint ](CreateCUint)),
/* 00 */ newCVTypeInfo(CBTypeInvalid ,"invalid" , optInvalidCreators()),
/* 01 */ newCVTypeInfo(CBTypeAny ,"any" , optAnyCreators [any ](nil)),
/* 02 */ newCVTypeInfo(CBTypeBool ,"bool" , optNormalCreators [bool ](CreateCBool)),
/* 03 */ newCVTypeInfo(CBTypeInt ,"int" , optNormalCreators [int ](CreateCInt)),
/* 04 */ newCVTypeInfo(CBTypeInt8 ,"int8" , optNormalCreators [int8 ](CreateCInt8)),
/* 05 */ newCVTypeInfo(CBTypeInt16 ,"int16" , optNormalCreators [int16 ](CreateCInt16)),
/* 06 */ newCVTypeInfo(CBTypeInt32 ,"int32" , optNormalCreators [int32 ](CreateCInt32)),
/* 07 */ newCVTypeInfo(CBTypeInt64 ,"int64" , optNormalCreators [int64 ](CreateCInt64)),
/* 08 */ newCVTypeInfo(CBTypeUint ,"uint" , optNormalCreators [uint ](CreateCUint)),
/* 09 */ newCVTypeInfo(CBTypeUint8 ,"uint8" ,
optNormalCreators[uint8](CreateCUint8),
// el creador de []uint8 debe de reportar el tipo Bytes y debe de llamar a su creador CreateCBytes
func(i *cBTypeInfo) { i.cByList = func(v any) CValue { return CreateCBytes(v.(Bytes)) } }),
/* 10 */ newCVTypeInfo(CBTypeUint16 ,"uint16" , optNormalCreators[uint16 ](CreateCUint16)),
/* 11 */ newCVTypeInfo(CBTypeUint32 ,"uint32" , optNormalCreators[uint32 ](CreateCUint32)),
/* 12 */ newCVTypeInfo(CBTypeUint64 ,"uint64" , optNormalCreators[uint64 ](CreateCUint64)),
/* 13 */ newCVTypeInfo(CBTypeUintptr ,"uintptr" , optNormalCreators[uintptr ](CreateCUintptr)),
/* 14 */ newCVTypeInfo(CBTypeDuration ,"duration" , optNormalCreators[Duration ](CreateCDuration)),
/* 10 */ newCVTypeInfo(CBTypeUint16 ,"uint16" , optNormalCreators [uint16 ](CreateCUint16)),
/* 11 */ newCVTypeInfo(CBTypeUint32 ,"uint32" , optNormalCreators [uint32 ](CreateCUint32)),
/* 12 */ newCVTypeInfo(CBTypeUint64 ,"uint64" , optNormalCreators [uint64 ](CreateCUint64)),
/* 13 */ newCVTypeInfo(CBTypeUintptr ,"uintptr" , optNormalCreators [uintptr ](CreateCUintptr)),
/* 14 */ newCVTypeInfo(CBTypeDuration ,"duration" , optNormalCreators [Duration ](CreateCDuration)),
/* 15 */ newCVTypeInfo(CBTypeFloat32 ,"float32" , optNormalCreators[float32 ](CreateCFloat32)),
/* 16 */ newCVTypeInfo(CBTypeFloat64 ,"float64" , optNormalCreators[float64 ](CreateCFloat64)),
/* 15 */ newCVTypeInfo(CBTypeFloat32 ,"float32" , optNormalCreators [float32 ](CreateCFloat32)),
/* 16 */ newCVTypeInfo(CBTypeFloat64 ,"float64" , optNormalCreators [float64 ](CreateCFloat64)),
/* 17 */ newCVTypeInfo(CBTypeComplex64 ,"complex64" , optNormalCreators[complex64 ](CreateCComplex64 )),
/* 18 */ newCVTypeInfo(CBTypeComplex128 ,"complex128" , optNormalCreators[complex128 ](CreateCComplex128)),
/* 17 */ newCVTypeInfo(CBTypeComplex64 ,"complex64" , optNormalCreators [complex64 ](CreateCComplex64 )),
/* 18 */ newCVTypeInfo(CBTypeComplex128 ,"complex128" , optNormalCreators [complex128 ](CreateCComplex128)),
// Big Int tiene una forma canonica de *big.Int, lo cual hace cambiar los constructores de Ptr ya que no lo
// debe des referenciar, en caso de que se pase por valor, debemos de convertirlo a un *BigInt, copiar su
@ -83,30 +86,31 @@ func newCBTypeInfos() *cBTypeInfos {
i.cByLazy= buildCreatorPByLazy[BigInt](CBTypeBigInt)
i.cByList= buildCreatorPByList[BigInt](CBTypeBigInt)
}),
/* 20 */ newCVTypeInfo(CBTypeHashAlg ,"hashalg" , optNormalCreators[HashAlg ](CreateCHashAlg)),
/* 20 */ newCVTypeInfo(CBTypeHashAlg ,"hashalg" , optNormalCreators [HashAlg ](CreateCHashAlg)),
/* 21 */ newCVTypeInfo(CBTypeString ,"string" , optNormalCreators[string ](CreateCString)),
/* 22 */ newCVTypeInfo(CBTypeUUID ,"uuid" , optNormalCreators[UUID ](CreateCUUID)),
/* 23 */ newCVTypeInfo(CBTypeBytes ,"bytes" , optNormalCreators[Bytes ](CreateCBytes)),
/* 24 */ newCVTypeInfo(CBTypeStack ,"stack" , optNormalCreators[Stack ](CreateCStack)),
/* 21 */ newCVTypeInfo(CBTypeString ,"string" , optNormalCreators [string ](CreateCString)),
/* 22 */ newCVTypeInfo(CBTypeUUID ,"uuid" , optNormalCreators [UUID ](CreateCUUID)),
/* 23 */ newCVTypeInfo(CBTypeBytes ,"bytes" , optNormalCreators [Bytes ](CreateCBytes)),
/* 24 */ newCVTypeInfo(CBTypeStack ,"stack" , optNormalCreators [Stack ](CreateCStack)),
/* 25 */ newCVTypeInfo(CBTypeDate ,"date" , optNormalCreators[Date ](CreateCDate)),
/* 26 */ newCVTypeInfo(CBTypeCValue ,"cvalue" , optNormalCreators[CValue ](CreateCCValue)),
/* 27 */ newCVTypeInfo(CBTypeReflect ,"cvalue" , optNormalCreators[Reflect ](CreateCReflect)),
/* 25 */ newCVTypeInfo(CBTypeDate ,"date" , optNormalCreators [Date ](CreateCDate)),
/* 26 */ newCVTypeInfo(CBTypeCValue ,"cvalue" , optNormalCreators [CValue ](CreateCCValue)),
/* 27 */ newCVTypeInfo(CBTypeReflect ,"cvalue" , optNormalCreators [Reflect ](CreateCReflect)),
/* 28 */ newCVTypeInfo(CBTypeObject ,"object" , optAnyCreators [any ](CreateCAny)),
// Los interfaces solo se evaluate en su forma canonical
/* 28 */ newCVTypeInfo(CBTypeMapPackable,"mappackable", optAnyCreators [MapPackable](CreateCMapPackable)),
/* 29 */ newCVTypeInfo(CBTypeMapPackable,"mappackable", optAnyCreators [MapPackable](CreateCMapPackable)),
/* 30 */ newCVTypeInfo(CBTypeObjPackable,"objpackable", optAnyCreators [ObjPackable](CreateCObjectPackable)),
/* 31 */ newCVTypeInfo(CBTypePackable ,"packable" , optAnyCreators [Packable ](CreateCPackable)),
/* 30 */ newCVTypeInfo(CBTypeMapPackable,"mappackable", optAnyCreators [MapPackable](CreateCMapPackable)),
/* 31 */ newCVTypeInfo(CBTypeObjPackable,"objpackable", optAnyCreators [ObjPackable](CreateCObjectPackable)),
/* 32 */ newCVTypeInfo(CBTypePackable ,"packable" , optAnyCreators [Packable ](CreateCPackable)),
/* 32 */ newCVTypeInfo(CBTypeContext ,"context" , optAnyCreators [Context ](CreateCContext)),
/* 33 */ newCVTypeInfo(CBTypeError ,"error" , optNormalCreators [error ](CreateCError)),
/* 34 */ newCVTypeInfo(CBTypeStringer ,"stringer" , optNormalCreators [Stringer ](CreateCStringer)) ,
/* 33 */ newCVTypeInfo(CBTypeContext ,"context" , optAnyCreators [Context ](CreateCContext)),
/* 34 */ newCVTypeInfo(CBTypeError ,"error" , optNormalCreators [error ](CreateCError)),
/* 35 */ newCVTypeInfo(CBTypeStringer ,"stringer" , optNormalCreators [Stringer ](CreateCStringer)) ,
/* 35 */ newCVTypeInfo(CBTypeNil , "nil" , optSameCreators (CreateCNil)),
/* 36 */ newCVTypeInfo(CBTypeNil , "nil" , optSameCreators (CreateCNil)),
}
@ -115,7 +119,10 @@ func newCBTypeInfos() *cBTypeInfos {
func (i *cBTypeInfos) createByReflection (value any) CValue {
func (i *cBTypeInfos) CreateByReflection(value any, vtype CVType) CValue {
rv := reflect.ValueOf(value)
if !rv.IsValid() {
return createCInvalidError(rv,CStateReflected,E.InvalidReflectValue)
@ -129,13 +136,182 @@ func (i *cBTypeInfos) createByReflection (value any) CValue {
return rf(rv)
}
tn := rt.String()
switch rt.Kind() {
// Los tipos soportados deben de haber sido capturados
// por el switch de tipos
case reflect.Struct : // createCValueAny
if /*vtype.c.IsComposite() ||*/ vtype.v != CBTypeObject {
return createCInvalidError(rv, CStateReflected,E.UnexpectedTypeReflected)
}
rf = createCValueRObj(rt.String())
case reflect.Func :
if /*!vtype.v.IsValid() ||*/ vtype.c != CCTypeLazy {
return createCInvalidError(rv, CStateReflected,E.UnexpectedTypeReflected)
}
if rt.NumIn() == 0 && rt.NumOut() == 1 {
// Si fuera el tipo del valor devuelto conocido ya lo habria
// interceptado el switch de tipos, devolvemos un lazy|any
//
et:= reflectKindToCType(rt.Out(0).Kind())
rf = createCValueRLazy(CVType { v : et.v, c : CCTypeLazy},rt.String())
}
case reflect.Slice,
reflect.Array :
if /*!vtype.v.IsValid() ||*/ vtype.c != CCTypeList {
return createCInvalidError(rv,CStateReflected,E.UnexpectedTypeReflected)
}
kv := reflectKindToCType(rt.Elem().Kind())
if kv.v != CBTypeInvalid {
rf = createCValueRList(kv,rt.String())
}
case reflect.Map :
if /*!vtype.v.IsValid() ||*/ vtype.c != CCTypeMap {
return createCInvalidError(rv,CStateReflected,E.UnexpectedTypeReflected)
}
if kt := reflectKindToCType(rt.Key().Kind()); kt.v.IsValid() {
if et := reflectKindToCType(rt.Elem().Kind()); et.v.IsValid() {
et.c = CCTypeMap
et.k = kt.k
rf = createCValueRMap(et,rt.String())
}
}
}
if rf == nil {
rf = createCValueRAny(rt.String())
}
i.mux.Lock()
i.cache[rt]=rf
i.mux.RUnlock()
i.mux.Unlock()
return rf(rv)
}
func createCValueRList (vtype CVType, tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vs := CStateReflected
// Código podría ser redundante
if !rv.IsValid() {
return createCInvalidError(rv,vs,E.InvalidReflectValue)
}
vt := vtype
tn := tname
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs |= CStateNil
} else {
vs |= CStateZero
}
}
return CValue{CVType: vt, CState: vs, anyVal: rv, strVal: tn, intVal: int64(ln)}
}
}
func createCValueRMap (vtype CVType, tname string) func (value reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vs := CStateReflected
// Código podría ser redundante
if !rv.IsValid() {
return createCInvalidError(rv,vs,E.InvalidReflectValue)
}
vt := vtype
tn := tname
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs |= CStateNil
} else {
vs |= CStateZero
}
}
return CValue{CVType: vt, CState: vs, anyVal: rv, strVal: tn, intVal: int64(ln)}
}
}
func createCValueRLazy (vtype CVType, tname string) func (value reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vs := CStateReflected
// Código podría ser redundante
if !rv.IsValid() {
return createCInvalidError(rv,vs,E.InvalidReflectValue)
}
vt := vtype
tn := tname
if rv.IsNil() {
vs |= CStateNil
}
return CValue {CVType: vt, CState: vs, strVal: tn, anyVal: rv}
}
}
func createCValueRObj (tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vs := CStateReflected
// Código podría ser redundante
if !rv.IsValid() {
return createCInvalidError(rv,vs,E.InvalidReflectValue)
}
tn := tname
return CValue{CVType: CVType { v: CBTypeObject }, CState: vs, strVal: tn, anyVal: rv}
}
}
func createCValueRAny (tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
// Código podría ser redundante
if !rv.IsValid() {
return createCInvalidError(rv,CStateReflected,E.InvalidReflectValue)
}
tn := tname
return CValue{CVType: CVType { v: CBTypeAny }, CState: CStateReflected, strVal: tn, anyVal: rv}
}
}
func reflectKindToCType (kind reflect.Kind) CVType {
switch kind {
case reflect.Invalid: return CVType{ v: CBTypeInvalid}
case reflect.Bool : return CVType{ v: CBTypeBool }
case reflect.Int : return CVType{ v: CBTypeInt }
case reflect.Int8 : return CVType{ v: CBTypeInt8 }
case reflect.Int16 : return CVType{ v: CBTypeInt16 }
case reflect.Int32 : return CVType{ v: CBTypeInt32 }
case reflect.Int64 : return CVType{ v: CBTypeInt64 }
case reflect.Uint : return CVType{ v: CBTypeUint }
case reflect.Uint8 : return CVType{ v: CBTypeUint8 }
case reflect.Uint16 : return CVType{ v: CBTypeUint16 }
case reflect.Uint32 : return CVType{ v: CBTypeUint32 }
case reflect.Uint64 : return CVType{ v: CBTypeUint64 }
case reflect.Uintptr: return CVType{ v: CBTypeUintptr}
case reflect.Float32: return CVType{ v: CBTypeFloat32}
case reflect.Float64: return CVType{ v: CBTypeFloat64}
case reflect.Complex64 : return CVType{ v: CBTypeComplex64 }
case reflect.Complex128 :return CVType{ v: CBTypeComplex128}
case reflect.String : return CVType{ v: CBTypeString }
case reflect.Struct : return CVType{ v: CBTypeObject }
case reflect.Array,
reflect.Slice : return CVType{ v: CBTypeAny, c: CCTypeList }
case reflect.Map : return CVType{ v: CBTypeAny, c: CCTypeMap }
case reflect.Func : return CVType{ v: CBTypeAny, c: CCTypeLazy }
}
return CVType{ v: CBTypeAny }
}

@ -43,5 +43,5 @@ const (
type CCType uint8
func (c CCType) IsValid () bool { return c > CCTypeNone && c < g.maxCCType }
func (c CCType) IsComposite() bool { return c > CCTypeNone && c < g.maxCCType }

@ -28,34 +28,54 @@
package cdts
// CState representa una serie de banderas de estado compactas para un valor.
// Cada bandera se representa como un bit individual usando iota y operadores bitwise.
const (
CStateInvalid CState = 1 << iota // Valor no válido o corrupto (inconsistencia grave)
CStateError // Hubo un error al construir el valor; el detalle está en strValue (StateError)
CStateNil // Valor explícitamente nulo
CStateZero // Valor es cero (valor por defecto)
CStateVersion // Contiene metadatos de versión
CStateReflected // El valor fue obtenido por reflexión
CStateSensitive // Valor sensible (requiere tratamiento especial)
CStateEncoded // El Valor esta codificado
CStateInvalid CState = 1 << iota
CStateError
CStateNil
CStateZero
CStateVersion
CStateReflected
CStateSensitive
CStateEncoded
CStateNone CState = 0 // Estado sin banderas activas
CStateNone CState = 0
cStateOps = CStateSensitive | CStateEncoded // Conjunto de estados operativos especiales
cStateOps= CStateSensitive | CStateEncoded
)
// CState define un conjunto de banderas compactas de tipo uint8.
type CState uint8
func (s CState) IsStateInvalid () bool { return s&CStateInvalid != 0 }
func (s CState) IsStateError () bool { return s&CStateError != 0 }
func (s CState) IsStateNil () bool { return s&CStateNil != 0 }
func (s CState) IsStateZero () bool { return s&CStateZero != 0 }
func (s CState) IsStateNilOrZero() bool { return s&(CStateZero |CStateNil) != 0 }
func (s CState) IsStateVersion () bool { return s&CStateVersion != 0 }
func (s CState) IsStateReflected() bool { return s&CStateReflected != 0 }
func (s CState) IsStateSensitive() bool { return s&CStateSensitive != 0 }
func (s CState) IsStateEncoded () bool { return s&CStateEncoded != 0 }
// IsStateInvalid indica si el estado representa un valor inválido.
func (s CState) IsStateInvalid() bool { return s&CStateInvalid != 0 }
// IsStateError indica que hubo un error al construir el valor.
// El mensaje o código de error se encuentra en strValue y se accede con StateError()
// de CValue.
func (s CState) IsStateError() bool { return s&CStateError != 0 }
// IsStateNil indica si el valor es nulo.
func (s CState) IsStateNil() bool { return s&CStateNil != 0 }
// IsStateZero indica si el valor es el valor por defecto (cero).
func (s CState) IsStateZero() bool { return s&CStateZero != 0 }
// IsStateNilOrZero indica si el valor es nulo o cero.
func (s CState) IsStateNilOrZero() bool { return s&(CStateNil|CStateZero) != 0 }
// IsStateVersion indica si el valor contiene información de versión.
func (s CState) IsStateVersion() bool { return s&CStateVersion != 0 }
// IsStateReflected indica si el valor proviene de reflexión.
func (s CState) IsStateReflected() bool { return s&CStateReflected != 0 }
// IsStateSensitive indica si el valor es sensible (por ejemplo, contraseñas).
func (s CState) IsStateSensitive() bool { return s&CStateSensitive != 0 }
// IsStateEncoded indica si el valorha sido codificado.
func (s CState) IsStateEncoded() bool { return s&CStateEncoded != 0 }

@ -200,7 +200,7 @@ func createCUints[T uints] (v T, t CBType) CValue {
if v == 0 {
return CValue{ CVType: CVType{ v: t }, CState : CStateZero }
}
if t == CBTypeUint64 || t == CBTypeUintptr && v > math.MaxInt64 {
if t == CBTypeUint64 || t == CBTypeUintptr && uint64(v) > math.MaxInt64 {
return CValue{ CVType: CVType{ v: t }, CState : CStateVersion, anyVal: v }
}
return CValue{ CVType: CVType{ v: t }, intVal: int64(v) }
@ -225,9 +225,12 @@ func createCList [T lists] (v T, t CBType) CValue {
}
func createCIfcs[T any] (v T, t CBType) CValue {
/*
if v == nil {
return CValue{ CVType: CVType{ v: t }, CState : CStateNil }
}
*/
return CValue{ CVType: CVType{ v: t }, anyVal: v }
}

@ -69,3 +69,6 @@ func (i CVType) KType () CBType {
func (i CVType) CType () CCType { return i.c }
func (i CVType) IsComposite () bool {
return i.c.IsComposite()
}

@ -0,0 +1,109 @@
// =============================================================================
// 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 AType 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 14/06/2025
// =============================================================================
package cvls
import (
"context"
"crypto"
"fmt"
"math"
"math/big"
"reflect"
"time"
)
type (
Bytes = []uint8
Stack = []struct{ Line string }
UUID = [16]byte
Reflect = reflect.Value
Date = time.Time
Duration= time.Duration
Stringer= fmt.Stringer
BigInt = big.Int
HashAlg = crypto.Hash
Packable= interface { P () }
MapPackable = interface { Map () }
ListPackable = interface { List () }
ObjPackable = interface { Object () }
Context = context.Context
)
type (
ints interface { int | int8 | int16 | int32 | int64 }
uints interface { uint | uint8 | uint16 | uint32 | uint64 | uintptr | Duration | HashAlg }
cmplx interface { complex64 | complex128 }
lists interface { Bytes | Stack }
)
var (
G = struct {
cTypes *cTypeInfos
} {
cTypes : newCTypeInfos(),
}
g = struct {
bigZero *BigInt
uuidZero UUID
maxBType BType
maxCType AType
minTime,
maxTime time.Time
}{
uuidZero : UUID{},
bigZero : big.NewInt(0),
maxCType : aMaxType,
maxBType : bMaxType,
minTime: time.Unix(0, math.MinInt64),
maxTime: time.Unix(0, math.MaxInt64),
}
E = struct {
UnexpectedTypeReflected,
InvalidReflectValue string
}{
UnexpectedTypeReflected : "::unexpected_type_reflected",
InvalidReflectValue : "::invalid_reflect_value",
}
)

@ -0,0 +1,52 @@
// =============================================================================
// 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 AType 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 14/06/2025
// =============================================================================
package cvls
const (
ATypeNone AType = iota // No representa ningún tipo de agregado
ATypeLazy // Agregado evaluado de forma perezosa (lazy evaluation)
ATypeList // Agregado representado como una lista
ATypeMap // Agregado representado como un mapa (clave-valor)
aMaxType // Límite superior del enumerado AType (debe ser el último)
)
// AType representa el tipo de agregado (Aggregate Type).
// Define la naturaleza del agregado: si es una lista, un mapa o un valor evaluado perezosamente.
// Es útil para indicar cómo deben interpretarse y procesarse los datos agregados.
type AType uint8
// IsValid devuelve true si el valor de AType es válido (dentro del rango definido por aMaxType).
func (c AType) IsValid() bool {
return c < aMaxType
}

@ -0,0 +1,112 @@
// =============================================================================
// 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 AType 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 14/06/2025
// =============================================================================
package cvls
const (
BTypeInvalid BType = iota // Tipo inválido o no inicializado
// Tipos básicos
BTypeAny // Tipo genérico que puede contener cualquier valor
BTypeBool // Booleano (true/false)
// Tipos enteros con signo
BTypeInt // Entero con signo (tamaño por defecto de la arquitectura)
BTypeInt8
BTypeInt16
BTypeInt32
BTypeInt64
// Tipos enteros sin signo
BTypeUint
BTypeUint8
BTypeUint16
BTypeUint32
BTypeUint64
BTypeUintptr // Representación sin signo de un puntero
BTypeDuration // Duración de tiempo (generalmente basada en int64)
// Tipos de punto flotante y complejos
BTypeFloat32
BTypeFloat64
BTypeComplex64
BTypeComplex128
// Tipos numéricos extendidos
BTypeBigInt // Números enteros de precisión arbitraria (math/big.Int)
BTypeHashAlg // Representación de un algoritmo de hash (enum o identificador)
// Tipos de datos compuestos y especiales
BTypeString
BTypeUUID // Identificador único universal (UUID)
BTypeBytes // Arreglo de bytes
BTypeStack // Pila (estructura de datos LIFO)
BTypeDate // Fecha y hora
BTypeCValue // Valor de tipo C (posiblemente interoperabilidad)
BTypeReflect // Valor reflejado (reflect.Value)
BTypeObject // Objeto genérico (interfaz, struct, etc.)
// Tipos que admiten empaquetado (serialización optimizada)
BTypeListPackable
BTypeMapPackable
BTypeObjPackable
BTypePackable // Tipo que puede ser empaquetado de forma genérica
// Tipos especiales
BTypeContext // Contexto (context.Context)
BTypeError // Error (error)
BTypeStringer // Interfaz fmt.Stringer
BTypeNil // Valor nulo
bMaxType // Límite superior (no usar directamente)
)
// BType representa un tipo base (Base Type) utilizado para describir el tipo primitivo
// de un valor en el sistema de tipos. Puede ser combinado con AType para formar un CType.
type BType uint8
// Check devuelve BTypeInvalid si el valor no es válido; de lo contrario, devuelve el valor original.
func (c BType) Check() BType {
if c >= bMaxType {
return BTypeInvalid
}
return c
}
// IsValid devuelve true si el valor de BType es válido (dentro del rango permitido, excluyendo BTypeInvalid).
func (c BType) IsValid() bool {
return c > BTypeInvalid && c < bMaxType
}

@ -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 AType 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/06/2025
// =============================================================================
package cvls
const (
CStateInvalid CState = 1 << iota // Valor inválido o corrupto (inconsistente)
CStateError // Hubo un error al construir el valor
CStateNil // Valor explícitamente nulo
CStateZero // Valor es cero (valor por defecto)
CStateVersion // Contiene metadatos de versión
CStateReflected // Valor obtenido mediante reflexión
CStateSensitive // Valor sensible (requiere tratamiento especial)
CStateEncoded // Valor fue codificado (ej. serializado)
CStateNone CState = 0 // Sin banderas activas
cStateOps = CStateSensitive | CStateEncoded // Banderas operativas especiales
)
// CState define un conjunto de banderas para el tipo CValue (compact value) indicando el
// estado del mismo
type CState uint8
// HasInvalid indica que el estado es inválido o inconsistente.
func (s CState) HasInvalid() bool { return s&CStateInvalid != 0 }
// HasError indica que hubo un error al construir el valor.
func (s CState) HasError() bool { return s&CStateError != 0 }
// HasNil indica que el valor es nulo explícitamente.
func (s CState) HasNil() bool { return s&CStateNil != 0 }
// HasZero indica que el valor es igual AType cero (valor por defecto).
func (s CState) HasZero() bool { return s&CStateZero != 0 }
// HasNilOrZero indica si el valor es nulo o cero.
func (s CState) HasNilOrZero() bool { return s&(CStateZero|CStateNil) != 0 }
// HasVersion indica que el valor contiene metainformación de versión.
func (s CState) HasVersion() bool { return s&CStateVersion != 0 }
// HasReflected indica que el valor fue obtenido mediante reflexión.
func (s CState) HasReflected() bool { return s&CStateReflected != 0 }
// HasSensitive indica que el valor contiene información sensible.
func (s CState) HasSensitive() bool { return s&CStateSensitive != 0 }
// HasEncoded indica que el valor ha sido codificado.
func (s CState) HasEncoded() bool { return s&CStateEncoded != 0 }
// HasAny verifica si alguna de las banderas especificadas está activa.
func (s CState) HasAny(flags CState) bool { return s&flags != 0 }

@ -0,0 +1,71 @@
// =============================================================================
// 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 AType 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 14/06/2025
// =============================================================================
package cvls
// CType representa un tipo compuesto (Compact Type) que combina:
// - un tipo base de valor (VType)
// - un tipo base de clave (KType), usado en estructuras de tipo mapa
// - un tipo de agregado (AType), que describe la naturaleza estructural (list, map, lazy, etc.)
type CType struct {
VType BType // Tipo del valor contenido
KType BType // Tipo de la clave, solo aplicable si es un mapa
AType AType // Tipo de agregado (list, map, lazy, etc.)
}
// CreateCTypeBase crea un CType simple, sin agregado, solo con tipo base de valor.
func CreateCTypeBase(btype BType) CType { return CType{VType: btype} }
// CreateCTypeList crea un CType que representa una lista de valores del tipo especificado.
func CreateCTypeList(btype BType) CType { return CType{VType: btype, AType: ATypeList} }
// CreateCTypeLazy crea un CType que representa un valor evaluado de forma perezosa.
func CreateCTypeLazy(btype BType) CType { return CType{VType: btype, AType: ATypeLazy} }
// CreateCTypeMap crea un CType que representa un mapa con tipo de valor y tipo de clave especificados.
func CreateCTypeMap(vType, kType BType) CType { return CType{VType: vType, KType: kType, AType: ATypeMap} }
// IsValid verifica si el CType es válido.
// - El tipo de valor debe ser válido.
// - El tipo de agregado debe ser válido.
// - Si el tipo es un mapa, también debe ser válido el tipo de clave.
func (c CType) IsValid() bool {
if !c.VType.IsValid() || !c.AType.IsValid() {
return false
}
if c.AType == ATypeMap && !c.KType.IsValid() {
return false
}
return true
}

@ -0,0 +1,331 @@
// =============================================================================
// 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 15/06/2025
// =============================================================================
package cvls
// cTypeInfo contiene metadatos y funciones creadoras de CValue para un tipo base específico (BType).
// Actúa como una tabla de despacho, proporcionando diferentes constructores según cómo se presente
// el valor de entrada (por valor, por puntero, como una función lazy o como una lista/slice).
type (
cTypeInfo struct {
valType BType // El tipo base (e.g., CBTypeInt, CBTypeString) al que se refiere este bloque de información.
name string // Un nombre legible para el BType.
cByVal func(any) CValue // Función creadora para valores pasados directamente por valor (e.g., int, string).
cByPtr func(any) CValue // Función creadora para valores pasados como punteros (e.g., *int, *string).
cByLazy func(any) CValue // Función creadora para valores encapsulados en una función de evaluación lazy (e.g., func() T).
cByList func(any) CValue // Función creadora para valores como un slice/lista (e.g., []T o []*T).
}
)
// newCTypeInfo crea una nueva instancia de cTypeInfo para un tipo base dado y su nombre.
// Utiliza el patrón de opciones funcionales para configurar las diversas funciones creadoras de CValue (cByVal, cByPtr, etc.).
//
// BType: El tipo base (e.g., CBTypeInt) para el cual se crea esta información.
// name: Un nombre descriptivo para el BType.
// opts: Funciones opcionales que modifican la cTypeInfo, típicamente utilizadas para establecer las funciones creadoras.
func newCTypeInfo(BType BType, name string, opts ...func(info *cTypeInfo)) *cTypeInfo {
// Inicializa la estructura cTypeInfo con los valores base.
vi := &cTypeInfo{
valType: BType,
name : name,
}
// Aplica todas las opciones funcionales proporcionadas para configurar la cTypeInfo,
// estableciendo los métodos de creación de CValue.
for _, opt := range opts {
opt(vi)
}
return vi
}
// optInvalidCreators es una opción funcional que establece todas las funciones creadoras de CValue
// dentro de una cTypeInfo a 'createCInvalid'.
// Esto se usa típicamente para BTypes que no deberían ser instanciados directamente a través de estos
// métodos de despacho, o para señalar un método de creación no soportado.
func optInvalidCreators() func(*cTypeInfo) {
return func (i *cTypeInfo) {
i.cByVal = createCInvalid // Asigna 'createCInvalid' al creador de valores directos.
i.cByPtr = createCInvalid // Asigna 'createCInvalid' al creador de punteros.
i.cByLazy = createCInvalid // Asigna 'createCInvalid' al creador de valores lazy.
i.cByList = createCInvalid // Asigna 'createCInvalid' al creador de listas.
}
}
// optSameCreators es una opción funcional que asigna una única función creadora de CValue
// a todos los métodos de despacho (por valor, por puntero, lazy, por lista) dentro de una cTypeInfo.
// Esto es útil cuando la lógica de creación de CValue es idéntica independientemente de cómo se presente el valor.
//
// cf: La función creadora de CValue a utilizar para todos los tipos de despacho.
func optSameCreators (cf func(any) CValue) func(info *cTypeInfo) {
return func(i *cTypeInfo) {
i.cByVal = cf // Asigna 'cf' al creador de valores directos.
i.cByPtr = cf // Asigna 'cf' al creador de punteros.
i.cByLazy = cf // Asigna 'cf' al creador de valores lazy.
i.cByList = cf // Asigna 'cf' al creador de listas.
}
}
// optWithCreators es una opción funcional que permite especificar una función creadora de CValue distinta
// para cada método de despacho (por valor, por puntero, lazy, por lista) dentro de una cTypeInfo.
// Proporciona la máxima flexibilidad para la configuración.
//
// cvalue: Función creadora para valores directos.
// cptr: Función creadora para punteros.
// clazy: Función creadora para valores lazy (funciones).
// clist: Función creadora para valores de lista (slices).
func optWithCreators(cvalue, cptr, clazy, clist func(any) CValue) func (*cTypeInfo) {
return func ( i *cTypeInfo) {
i.cByVal = cvalue // Establece el creador para valores directos.
i.cByPtr = cptr // Establece el creador para punteros.
i.cByLazy = clazy // Establece el creador para valores lazy.
i.cByList = clist // Establece el creador para listas.
}
}
// optAnyCreators es una opción funcional genérica que configura las funciones creadoras
// para usar principalmente 'CreateCAny' para la mayoría de los métodos de despacho.
//
// Si se proporciona una 'byValueFn' específica, se utilizará para 'cByVal' (manejando la conversión de tipo desde 'any').
// De lo contrario, 'CreateCAny' también se utilizará para 'cByVal'.
//
// T: El tipo concreto que espera 'byValueFn'.
// byValueFn: Una función creadora opcional para valores directos de tipo T.
// Si es nil, CreateCAny se usará para cByVal.
func optAnyCreators [T any](byValueFn func(v T) CValue) func (*cTypeInfo) {
var cf func(any) CValue
if byValueFn != nil {
// Si se proporciona un creador de valor específico, lo envuelve para manejar la entrada 'any'.
cf = func(v any) CValue {
return byValueFn(v.(T)) // Asume que 'v' puede ser asertado al tipo T.
}
} else {
// Si no hay un creador de valor específico, por defecto usa el genérico CreateCAny.
cf = CreateCAny
}
return func (i *cTypeInfo) {
i.cByVal = cf // Establece el creador para valores directos (específico o genérico).
i.cByPtr = CreateCAny // Establece el creador para punteros al manejador genérico.
i.cByLazy = CreateCAny // Establece el creador para valores lazy al manejador genérico.
i.cByList = CreateCAny // Establece el creador para listas al manejador genérico.
}
}
// optAnyPCreators es una opción funcional genérica que configura las funciones creadoras
// específicamente para tipos de puntero (e.g., *T), listas de punteros ([]*T), y
// funciones lazy que devuelven punteros (func()*T).
//
// byPtrFnc: La función creadora específica para valores pasados como punteros de tipo *T.
// T: El tipo base concreto para el cual se configuran los creadores de puntero, lista de punteros y lazy de punteros.
func optAnyPCreators [T any](byPtrFnc func(v *T) CValue) func (*cTypeInfo) {
return func(i *cTypeInfo) {
// Envuelve el creador de puntero proporcionado para manejar la entrada 'any'
// asertándola a *T.
cf := func(v any) CValue { return byPtrFnc(v.(*T)) }
i.cByPtr = cf // Establece el creador para punteros.
// Construye y asigna creadores específicos para listas de punteros y
// funciones lazy que devuelven punteros.
i.cByList = buildCreatorPByList[T](i.valType) // Maneja []T, específicamente []*T.
i.cByLazy = buildCreatorPByLazy[T](i.valType) // Maneja func()T, específicamente func()*T.
}
}
// optNormalCreators es una opción funcional genérica que configura todas las funciones creadoras de CValue
// (por valor, por puntero, por lista, por lazy) basándose en un creador base proporcionado para valores directos.
// Es adecuada para la mayoría de los tipos "normales" donde las formas de puntero, lista y lazy
// pueden derivarse de la forma de valor.
//
// T: El tipo concreto para el cual se están construyendo los creadores.
// byValueFn: La función creadora base para valores directos de tipo T.
func optNormalCreators [T any](byValueFn func(v T) CValue) func(*cTypeInfo) {
return func(i *cTypeInfo) {
// Envuelve el creador de valor proporcionado para manejar la entrada 'any' asertándola a T.
vf := func(v any) CValue { return byValueFn(v.(T))}
i.cByVal = vf // Establece el creador para valores directos.
// Construye y asigna creadores específicos para punteros, listas y funciones lazy.
// Estos creadores construidos usarán internamente la 'byValueFn' para convertir
// el valor desreferenciado o evaluado.
i.cByPtr = buildCreatorByPtr [T](i.valType,byValueFn) // Maneja *T (desreferencia a T).
i.cByList = buildCreatorByList[T](i.valType) // Maneja []T.
i.cByLazy = buildCreatorByLazy[T](i.valType) // Maneja func()T.
}
}
// buildCreatorByPtr construye una función creadora de CValue para tipos de puntero (*T).
// Toma una entrada 'any', la aserta a *T, maneja punteros nil, y luego
// desreferencia el puntero para pasar el valor a la 'byValueFn' proporcionada.
//
// T: El tipo base (no puntero) que maneja 'byValueFn'.
// BType: El CBType correspondiente al tipo base T. Usado para CTypeBase cuando es nil.
// byValueFn: La función creadora de CValue para valores directos de tipo T.
func buildCreatorByPtr [T any](BType BType, byValueFn func(v T) CValue) func(any) CValue {
return func(v any) CValue {
// Intenta asertar la entrada 'any' a un puntero de tipo *T.
vl, ok := v.(*T)
if !ok {
// Si la aserción de tipo falla, significa que la entrada no es *T.
// Devuelve un CValue inválido, con un error indicando una discordancia de tipo.
return createCInvalidError(v, CStateReflected, E.UnexpectedTypeReflected)
}
// Si el puntero en sí es nil, devuelve un CValue indicando un estado nil.
// El CType reflejará el tipo base T, pero el valor es nil.
if vl == nil {
return CValue{ctype: CreateCTypeBase(BType), state: CStateNil}
}
// Si el puntero no es nil, desreferéncialo (*vl) y
// usa la 'byValueFn' proporcionada para crear el CValue a partir del valor subyacente.
return byValueFn(*vl)
}
}
// buildCreatorByList construye una función creadora de CValue para tipos de lista (slices) ([]T).
// Toma una entrada 'any', la aserta a []T, maneja slices nil, slices vacíos,
// y almacena la lista en 'anyVal' junto con su longitud en 'intVal'.
//
// T: El tipo de elemento del slice.
// btype: El CBType correspondiente al tipo de elemento T. Usado para CTypeList.
func buildCreatorByList[T any](btype BType) func(any) CValue {
return func(v any) CValue {
// Intenta asertar la entrada 'any' a un slice de tipo []T.
vl, ok := v.([]T)
if !ok {
// Si la aserción de tipo falla, Devuelve un CValue inválido, con un error
// indicando una discordancia de tipo.
return createCInvalidError(v, CStateReflected, E.UnexpectedTypeReflected)
}
ln := len(vl) // Obtiene la longitud del slice.
var vs CState // Variable para almacenar el estado de CValue.
// Determina el estado del slice.
if vl == nil {
// Si el slice en sí es nil, establece CStateNil.
vs = CStateNil
return CValue{ ctype: CreateCTypeList(btype) , state: vs } // Devuelve inmediatamente para un slice nil.
}
// Si el slice no es nil pero su longitud es 0, establece CStateZero.
// De lo contrario, no se establece ningún flag de estado específico (implica CStateNone).
if ln == 0 {
vs = CStateZero
} else {
vs = CStateNone // Establece explícitamente a None si no es nil y no es de longitud cero.
}
// Devuelve el CValue con el estado determinado, el slice en anyVal y su longitud en intVal.
return CValue{ ctype : CreateCTypeList(btype) , state: vs, anyVal: vl, intVal: int64(ln) }
}
}
// buildCreatorPByList construye una función creadora de CValue para listas de tipos de puntero ([]*T).
// Toma una entrada 'any', la aserta a []*T, maneja slices nil, slices vacíos,
// y almacena la lista en 'anyVal' junto con su longitud en 'intVal'.
//
// T: El tipo de elemento base del slice de punteros (e.g., si el slice es []*int, T es int).
// btype: El CBType correspondiente al tipo de elemento base T. Usado para CTypeList.
func buildCreatorPByList[T any](btype BType) func(any) CValue {
return func(v any) CValue {
// Intenta asertar la entrada 'any' a un slice de punteros de tipo []*T.
vl, ok := v.([]*T)
if !ok {
// Si la aserción de tipo falla, devuelve un CValue inválido.
return createCInvalidError(v, CStateReflected, E.UnexpectedTypeReflected)
}
ln := len(vl) // Obtiene la longitud del slice.
var vs CState // Variable para almacenar el estado de CValue.
// Determina el estado del slice.
if vl == nil {
// Si el slice en sí es nil, establece CStateNil.
vs = CStateNil
return CValue{ ctype : CreateCTypeList(btype), state: vs } // Devuelve inmediatamente para un slice nil.
}
// Si el slice no es nil pero su longitud es 0, establece CStateZero.
// De lo contrario, no se establece ningún flag de estado específico (implica CStateNone).
if ln == 0 {
vs = CStateZero
} else {
vs = CStateNone // Establece explícitamente a None si no es nil y no es de longitud cero.
}
// Devuelve el CValue con el estado determinado, el slice en anyVal y su longitud en intVal.
return CValue{ ctype : CreateCTypeList(btype) , state: vs, anyVal: vl, intVal: int64(ln) }
}
}
// buildCreatorByLazy construye una función creadora de CValue para tipos de evaluación lazy (func()T).
// Toma una entrada 'any', la aserta a func()T, maneja funciones nil,
// y almacena la función en 'anyVal'.
//
// T: El tipo de retorno de la función lazy.
// btype: El CBType correspondiente al tipo de retorno T. Usado para CTypeLazy.
func buildCreatorByLazy[T any](btype BType) func(any) CValue {
return func(v any) CValue {
// Intenta asertar la entrada 'any' a una función que devuelve el tipo T.
vl, ok := v.(func()T)
if !ok {
// Si la aserción de tipo falla, devuelve un CValue inválido.
return createCInvalidError(v, CStateReflected, E.UnexpectedTypeReflected)
}
// Si la función en sí es nil, devuelve un CValue indicando un estado nil.
if vl == nil {
return CValue{ ctype: CreateCTypeLazy(btype), state: CStateNil }
}
// De lo contrario, devuelve un CValue con la función lazy almacenada en anyVal.
return CValue{ ctype: CreateCTypeLazy(btype), anyVal: vl }
}
}
// buildCreatorPByLazy construye una función creadora de CValue para tipos de evaluación lazy
// que devuelven punteros (func()*T).
// Toma una entrada 'any', la aserta a func()*T, maneja funciones nil,
// y almacena la función en 'anyVal'.
//
// T: El tipo base del puntero devuelto por la función lazy (e.g., si func() *int, T es int).
// btype: El CBType correspondiente al tipo de retorno base T. Usado para CTypeLazy.
func buildCreatorPByLazy[T any](btype BType) func(any) CValue {
return func(v any) CValue {
// Intenta asertar la entrada 'any' a una función que devuelve un puntero de tipo *T.
vl, ok := v.(func()*T)
if !ok {
// Si la aserción de tipo falla, devuelve un CValue inválido.
return createCInvalidError(v, CStateReflected, E.UnexpectedTypeReflected)
}
// Si la función en sí es nil, devuelve un CValue indicando un estado nil.
if vl == nil {
return CValue{ ctype: CreateCTypeLazy(btype), state: CStateNil }
}
// De lo contrario, devuelve un CValue con la función lazy almacenada en anyVal.
return CValue{ ctype: CreateCTypeLazy(btype), anyVal: vl }
}
}

@ -0,0 +1,457 @@
// =============================================================================
// 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 16/06/2025
// =============================================================================
package cvls
import (
"reflect"
"sync"
)
type (
cTypeInfos struct {
types []*cTypeInfo
mux sync.RWMutex
cache map[reflect.Type]func(reflect.Value) CValue
}
)
func newCTypeInfos() *cTypeInfos {
vi := &cTypeInfos{
cache : make(map[reflect.Type]func(reflect.Value) CValue),
}
vi.types = []*cTypeInfo{
/* 00 */ newCTypeInfo(BTypeInvalid ,"invalid" , optInvalidCreators()),
/* 01 */ newCTypeInfo(BTypeAny ,"any" , optAnyCreators [any ](nil)),
/* 02 */ newCTypeInfo(BTypeBool ,"bool" , optNormalCreators [bool ](CreateCBool)),
/* 03 */ newCTypeInfo(BTypeInt ,"int" , optNormalCreators [int ](CreateCInt)),
/* 04 */ newCTypeInfo(BTypeInt8 ,"int8" , optNormalCreators [int8 ](CreateCInt8)),
/* 05 */ newCTypeInfo(BTypeInt16 ,"int16" , optNormalCreators [int16 ](CreateCInt16)),
/* 06 */ newCTypeInfo(BTypeInt32 ,"int32" , optNormalCreators [int32 ](CreateCInt32)),
/* 07 */ newCTypeInfo(BTypeInt64 ,"int64" , optNormalCreators [int64 ](CreateCInt64)),
/* 08 */ newCTypeInfo(BTypeUint ,"uint" , optNormalCreators [uint ](CreateCUint)),
/* 09 */ newCTypeInfo(BTypeUint8 ,"uint8" ,
optNormalCreators[uint8](CreateCUint8),
// el creador de []uint8 debe de reportar el tipo Bytes y debe de llamar a su creador CreateCBytes
func(i *cTypeInfo) { i.cByList = func(v any) CValue { return CreateCBytes(v.(Bytes)) } }),
/* 10 */ newCTypeInfo(BTypeUint16 ,"uint16" , optNormalCreators [uint16 ](CreateCUint16)),
/* 11 */ newCTypeInfo(BTypeUint32 ,"uint32" , optNormalCreators [uint32 ](CreateCUint32)),
/* 12 */ newCTypeInfo(BTypeUint64 ,"uint64" , optNormalCreators [uint64 ](CreateCUint64)),
/* 13 */ newCTypeInfo(BTypeUintptr ,"uintptr" , optNormalCreators [uintptr ](CreateCUintptr)),
/* 14 */ newCTypeInfo(BTypeDuration ,"duration" , optNormalCreators [Duration ](CreateCDuration)),
/* 15 */ newCTypeInfo(BTypeFloat32 ,"float32" , optNormalCreators [float32 ](CreateCFloat32)),
/* 16 */ newCTypeInfo(BTypeFloat64 ,"float64" , optNormalCreators [float64 ](CreateCFloat64)),
/* 17 */ newCTypeInfo(BTypeComplex64 ,"complex64" , optNormalCreators [complex64 ](CreateCComplex64 )),
/* 18 */ newCTypeInfo(BTypeComplex128 ,"complex128" , optNormalCreators [complex128 ](CreateCComplex128)),
// Big Int tiene una forma canonica de *big.Int, lo cual hace cambiar los constructores de Ptr ya que no lo
// debe des referenciar, en caso de que se pase por valor, debemos de convertirlo a un *BigInt, copiar su
// valor y una vez pasado llamar a la funcion de creacion CreateCBigInt
/* 19 */ newCTypeInfo(BTypeBigInt ,"bigint" , func(i *cTypeInfo) {
i.cByVal = func (v any) CValue {
bv := v.(BigInt)
return CreateCBigInt(new(BigInt).Set(&bv))
}
i.cByPtr = func (v any) CValue { return CreateCBigInt(v.(*BigInt)) }
i.cByLazy= buildCreatorPByLazy[BigInt](BTypeBigInt)
i.cByList= buildCreatorPByList[BigInt](BTypeBigInt)
}),
/* 20 */ newCTypeInfo(BTypeHashAlg ,"hashalg" , optNormalCreators [HashAlg ](CreateCHashAlg)),
/* 21 */ newCTypeInfo(BTypeString ,"string" , optNormalCreators [string ](CreateCString)),
/* 22 */ newCTypeInfo(BTypeUUID ,"uuid" , optNormalCreators [UUID ](CreateCUUID)),
/* 23 */ newCTypeInfo(BTypeBytes ,"bytes" , optNormalCreators [Bytes ](CreateCBytes)),
/* 24 */ newCTypeInfo(BTypeStack ,"stack" , optNormalCreators [Stack ](CreateCStack)),
/* 25 */ newCTypeInfo(BTypeDate ,"date" , optNormalCreators [Date ](CreateCDate)),
/* 26 */ newCTypeInfo(BTypeCValue ,"cvalue" , optNormalCreators [CValue ](CreateCCValue)),
/* 27 */ newCTypeInfo(BTypeReflect ,"reflect" , optNormalCreators [Reflect ](CreateCReflect)),
/* 28 */ newCTypeInfo(BTypeObject ,"object" , optAnyCreators [any ](CreateCAny)),
// Los interfaces solo se evaluate en su forma canonical
/* 29 */ newCTypeInfo(BTypeListPackable ,"listpackable",optAnyCreators [ListPackable](CreateCListPackable)),
/* 30 */ newCTypeInfo(BTypeMapPackable ,"mappackable", optAnyCreators [MapPackable](CreateCMapPackable)),
/* 31 */ newCTypeInfo(BTypeObjPackable ,"objpackable", optAnyCreators [ObjPackable](CreateCObjectPackable)),
/* 32 */ newCTypeInfo(BTypePackable ,"packable" , optAnyCreators [Packable ](CreateCPackable)),
/* 33 */ newCTypeInfo(BTypeContext ,"context" , optAnyCreators [Context ](CreateCContext)),
/* 34 */ newCTypeInfo(BTypeError ,"error" , optNormalCreators [error ](CreateCError)),
/* 35 */ newCTypeInfo(BTypeStringer ,"stringer" , optNormalCreators [Stringer ](CreateCStringer)) ,
/* 36 */ newCTypeInfo(BTypeNil , "nil" , optSameCreators (CreateCNil)),
}
return vi
}
func (i *cTypeInfos) createCValue (value any) CValue {
if value == nil {
return CValue{ ctype: CreateCTypeBase(BTypeAny), state: CStateNil }
}
var f func(any) CValue = nil
switch value.(type) {
/* Valores simples */
//case any : f = i.types[BTypeAny ].cByVal
case bool : f = i.types[BTypeBool ].cByVal
case int : f = i.types[BTypeInt ].cByVal
case int8 : f = i.types[BTypeInt8 ].cByVal
case int16 : f = i.types[BTypeInt16 ].cByVal
case int32 : f = i.types[BTypeInt32 ].cByVal
case int64 : f = i.types[BTypeInt64 ].cByVal
case uint : f = i.types[BTypeUint ].cByVal
case uint8 : f = i.types[BTypeUint8 ].cByVal
case uint16 : f = i.types[BTypeUint16 ].cByVal
case uint32 : f = i.types[BTypeUint32 ].cByVal
case uint64 : f = i.types[BTypeUint64 ].cByVal
case uintptr : f = i.types[BTypeUintptr ].cByVal
case float32 : f = i.types[BTypeFloat32 ].cByVal
case float64 : f = i.types[BTypeFloat64 ].cByVal
case complex64 : f = i.types[BTypeComplex64 ].cByVal
case complex128 : f = i.types[BTypeComplex128 ].cByVal
case Date : f = i.types[BTypeDate ].cByVal
case Duration : f = i.types[BTypeDuration ].cByVal
case string : f = i.types[BTypeString ].cByVal
case Bytes : f = i.types[BTypeBytes ].cByVal
case Stack : f = i.types[BTypeStack ].cByVal
case CValue : f = i.types[BTypeCValue ].cByVal
case Context : f = i.types[BTypeContext ].cByVal
case error : f = i.types[BTypeError ].cByVal
case Reflect : f = i.types[BTypeReflect ].cByVal
case UUID : f = i.types[BTypeUUID ].cByVal
case HashAlg : f = i.types[BTypeHashAlg ].cByVal
case Stringer : f = i.types[BTypeStringer ].cByVal
case BigInt : f = i.types[BTypeBigInt ].cByVal
case MapPackable : f = i.types[BTypeMapPackable ].cByVal
case ListPackable : f = i.types[BTypeListPackable ].cByVal
case ObjPackable : f = i.types[BTypeObjPackable ].cByVal
case Packable : f = i.types[BTypePackable ].cByVal
/* Valores Listas */
case []any : f = i.types[BTypeAny ].cByList
case []bool : f = i.types[BTypeBool ].cByList
case []int : f = i.types[BTypeInt ].cByList
case []int8 : f = i.types[BTypeInt8 ].cByList
case []int16 : f = i.types[BTypeInt16 ].cByList
case []int32 : f = i.types[BTypeInt32 ].cByList
case []int64 : f = i.types[BTypeInt64 ].cByList
case []uint : f = i.types[BTypeUint ].cByList
// ya establecido como tipo base Bytes
//case []uint8 :
//
case []uint16 : f = i.types[BTypeUint16 ].cByList
case []uint32 : f = i.types[BTypeUint32 ].cByList
case []uint64 : f = i.types[BTypeUint64 ].cByList
case []uintptr : f = i.types[BTypeUintptr ].cByList
case []float32 : f = i.types[BTypeFloat32 ].cByList
case []float64 : f = i.types[BTypeFloat64 ].cByList
case []complex64 : f = i.types[BTypeComplex64 ].cByList
case []complex128 :f = i.types[BTypeComplex128 ].cByList
case []Duration : f = i.types[BTypeDuration ].cByList
case []Date : f = i.types[BTypeDate ].cByList
case []string : f = i.types[BTypeString ].cByList
case []Bytes : f = i.types[BTypeBytes ].cByList
//case []Stack : f = i.types[BTypeStack ].cByList
case []CValue : f = i.types[BTypeCValue ].cByList
//case []Context : f = i.types[BTypeContext ].cByList
case []error : f = i.types[BTypeError ].cByList
case []UUID : f = i.types[BTypeUUID ].cByList
//case []HashAlg : f = i.types[BTypeHashAlg ].cByList
//case []Reflect : f = i.types[BTypeReflect ].cByList
//case []Stringer : f = i.types[BTypeStringer ].cByList
//case []*BigInt : f = i.types[BTypeBigInt ].cByList
//case []MapPackable : f = i.types[BTypeMapPackable ].cByList
//case []ListPackable : f = i.types[BTypeListPackable ].cByList
//case []ObjPackable : f = i.types[BTypeObjPackable ].cByList
//case []Packable : f = i.types[BTypePackable ].cByList
/* Valores pasados por punteros */
//case *any : f = i.types[ 1/* Any */].cByPtr
case *bool : f = i.types[BTypeBool ].cByPtr
case *int : f = i.types[BTypeInt ].cByPtr
case *int8 : f = i.types[BTypeInt8 ].cByPtr
case *int16 : f = i.types[BTypeInt16 ].cByPtr
case *int32 : f = i.types[BTypeInt32 ].cByPtr
case *int64 : f = i.types[BTypeInt64 ].cByPtr
case *uint : f = i.types[BTypeUint ].cByPtr
case *uint8 : f = i.types[BTypeUint8 ].cByPtr
case *uint16 : f = i.types[BTypeUint16 ].cByPtr
case *uint32 : f = i.types[BTypeUint32 ].cByPtr
case *uint64 : f = i.types[BTypeUint64 ].cByPtr
case *uintptr : f = i.types[BTypeUintptr ].cByPtr
case *float32 : f = i.types[BTypeFloat32 ].cByPtr
case *float64 : f = i.types[BTypeFloat64 ].cByPtr
case *complex64 : f = i.types[BTypeComplex64 ].cByPtr
case *complex128 : f = i.types[BTypeComplex128 ].cByPtr
case *Duration : f = i.types[BTypeDuration ].cByPtr
case *Date : f = i.types[BTypeDate ].cByPtr
case *string : f = i.types[BTypeString ].cByPtr
case *Bytes : f = i.types[BTypeBytes ].cByPtr
case *Stack : f = i.types[BTypeStack ].cByPtr
case *CValue : f = i.types[BTypeCValue ].cByPtr
//case *Context : f = i.types[BTypeContext ].cByPtr
//case *error : f = i.types[BTypeError ].cByPtr
//case *UUID : f = i.types[BTypeUUID ].cByPtr
//case *HashAlg : f = i.types[BTypeHashAlg ].cByPtr
//case *Reflect : f = i.types[BTypeReflect ].cByPtr
//case *Stringer : f = i.types[BTypeStringer ].cByPtr
//case *BigInt : f = i.types[BTypeBigInt ].cByPtr
//case *MapPackable : f = i.types[BTypeMapPackable ].cByPtr
//case *ListPackable : f = i.types[BTypeListPackable ].cByPtr
//case *ObjPackable : f = i.types[BTypeObjPackable ].cByPtr
//case *Packable : f = i.types[BTypePackable ].cByPtr
/* Valores pasados por functions Lazys */
case func()any : f = i.types[BTypeAny ].cByLazy
case func()bool : f = i.types[BTypeBool ].cByLazy
case func()int : f = i.types[BTypeInt ].cByLazy
case func()int8 : f = i.types[BTypeInt8 ].cByLazy
case func()int16 : f = i.types[BTypeInt16 ].cByLazy
case func()int32 : f = i.types[BTypeInt32 ].cByLazy
case func()int64 : f = i.types[BTypeInt64 ].cByLazy
case func()uint : f = i.types[BTypeUint ].cByLazy
case func()uint8 : f = i.types[BTypeUint8 ].cByLazy
case func()uint16 : f = i.types[BTypeUint16 ].cByLazy
case func()uint32 : f = i.types[BTypeUint32 ].cByLazy
case func()uint64 : f = i.types[BTypeUint64 ].cByLazy
case func()uintptr : f = i.types[BTypeUintptr ].cByLazy
case func()float32 : f = i.types[BTypeFloat32 ].cByLazy
case func()float64 : f = i.types[BTypeFloat64 ].cByLazy
case func()complex64 : f = i.types[BTypeComplex64 ].cByLazy
case func()complex128 :f = i.types[BTypeComplex128 ].cByLazy
case func()Duration : f = i.types[BTypeDuration ].cByLazy
case func()Date : f = i.types[BTypeDate ].cByLazy
case func()string : f = i.types[BTypeString ].cByLazy
case func()Bytes : f = i.types[BTypeBytes ].cByLazy
case func()Stack : f = i.types[BTypeStack ].cByLazy
case func()CValue : f = i.types[BTypeCValue ].cByLazy
case func()Context : f = i.types[BTypeContext ].cByLazy
case func()error : f = i.types[BTypeError ].cByLazy
case func()UUID : f = i.types[BTypeUUID ].cByLazy
case func()HashAlg : f = i.types[BTypeHashAlg ].cByLazy
case func()Reflect : f = i.types[BTypeReflect ].cByLazy
case func()Stringer : f = i.types[BTypeStringer ].cByLazy
case func()*BigInt : f = i.types[BTypeBigInt ].cByLazy
case func()MapPackable : f = i.types[BTypeMapPackable ].cByLazy
case func()ListPackable : f = i.types[BTypeListPackable ].cByLazy
case func()ObjPackable : f = i.types[BTypeObjPackable ].cByLazy
case func()Packable : f = i.types[BTypePackable ].cByLazy
}
if f != nil {
return f(value)
}
return i.CreateByReflection(value)
}
func (i *cTypeInfos) CreateByReflection(value any) CValue {
rv := reflect.ValueOf(value)
if !rv.IsValid() {
return createCInvalidError(rv,CStateReflected,E.InvalidReflectValue)
}
rt := rv.Type()
i.mux.RLock()
rf,ok := i.cache[rt]
i.mux.RUnlock()
if ok {
return rf(rv)
}
switch rt.Kind() {
// Los tipos soportados deben de haber sido capturados
// por el switch de tipos
case reflect.Struct : // createCValueAny
rf = createCValueRObj(rt.String())
case reflect.Func :
if rt.NumIn() == 0 && rt.NumOut() == 1 {
// Si fuera el tipo del valor devuelto conocido ya lo habria
// interceptado el switch de tipos, devolvemos un lazy|any
//
et:= reflectKindToCType(rt.Out(0).Kind())
rf = createCValueRLazy(CreateCTypeLazy(et.VType),rt.String())
}
case reflect.Slice,
reflect.Array :
vt := reflectKindToCType(rt.Elem().Kind())
if vt.VType != BTypeInvalid {
rf = createCValueRList(CreateCTypeList(vt.VType),rt.String())
}
case reflect.Map :
if kt := reflectKindToCType(rt.Key().Kind()); kt.VType.IsValid() {
if et := reflectKindToCType(rt.Elem().Kind()); et.VType.IsValid() {
rf = createCValueRMap(CreateCTypeMap(et.VType,kt.VType),rt.String())
}
}
}
if rf == nil {
rf = createCValueRAny(rt.String())
}
i.mux.Lock()
i.cache[rt]=rf
i.mux.Unlock()
return rf(rv)
}
func createCValueRList (vtype CType, tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vt := vtype
tn := tname
vs := CStateReflected
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs |= CStateNil
} else {
vs |= CStateZero
}
}
return CValue{ctype: vt, state: vs, anyVal: rv, strVal: tn, intVal: int64(ln)}
}
}
func createCValueRMap (vtype CType, tname string) func (value reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vt := vtype
tn := tname
vs := CStateReflected
ln := rv.Len()
if ln == 0 {
if rv.IsNil() {
vs |= CStateNil
} else {
vs |= CStateZero
}
}
return CValue{ctype: vt , state: vs, anyVal: rv, strVal: tn, intVal: int64(ln)}
}
}
func createCValueRLazy (vtype CType, tname string) func (value reflect.Value) CValue {
return func(rv reflect.Value) CValue {
vt := vtype
tn := tname
vs := CStateReflected
if rv.IsNil() {
vs |= CStateNil
}
return CValue {ctype: vt, state: vs, strVal: tn, anyVal: rv}
}
}
func createCValueRObj (tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
tn := tname
return CValue{ctype: CreateCTypeBase (BTypeObject), state: CStateReflected, strVal: tn, anyVal: rv}
}
}
func createCValueRAny (tname string) func(reflect.Value) CValue {
return func(rv reflect.Value) CValue {
tn := tname
return CValue{ ctype: CreateCTypeBase (BTypeAny), state: CStateReflected, strVal: tn, anyVal: rv}
}
}
func reflectKindToCType (kind reflect.Kind) CType {
switch kind {
case reflect.Invalid: return CType{ VType: BTypeInvalid }
case reflect.String : return CType{ VType: BTypeString }
case reflect.Int : return CType{ VType: BTypeInt }
case reflect.Uint : return CType{ VType: BTypeUint }
case reflect.Bool : return CType{ VType: BTypeBool }
case reflect.Int8 : return CType{ VType: BTypeInt8 }
case reflect.Int16 : return CType{ VType: BTypeInt16 }
case reflect.Int32 : return CType{ VType: BTypeInt32 }
case reflect.Int64 : return CType{ VType: BTypeInt64 }
case reflect.Uint8 : return CType{ VType: BTypeUint8 }
case reflect.Uint16 : return CType{ VType: BTypeUint16 }
case reflect.Uint32 : return CType{ VType: BTypeUint32 }
case reflect.Uint64 : return CType{ VType: BTypeUint64 }
case reflect.Uintptr: return CType{ VType: BTypeUintptr }
case reflect.Float32: return CType{ VType: BTypeFloat32 }
case reflect.Float64: return CType{ VType: BTypeFloat64 }
case reflect.Struct : return CType{ VType: BTypeObject }
case reflect.Array,
reflect.Slice : return CType{ VType: BTypeAny, AType: ATypeList }
case reflect.Map : return CType{ VType: BTypeAny, AType: ATypeMap }
case reflect.Func : return CType{ VType: BTypeAny, AType: ATypeLazy }
case reflect.Complex64 : return CType{ VType: BTypeComplex64 }
case reflect.Complex128: return CType{ VType: BTypeComplex128}
}
return CType{ VType: BTypeAny }
}

@ -0,0 +1,270 @@
// =============================================================================
// 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 15/06/2025
// =============================================================================
package cvls
import (
"math"
"reflect"
)
// CValue representa un valor de tipo dinámico con su tipo base (ctype), estado (state) y valores posibles.
type (
CValue struct {
_ [0]func() // Padding para prevenir comparaciones automáticas (zero-size field)
ctype CType // Tipo base del valor
state CState // Estado del valor (Zero, Nil, Error, etc.)
intVal int64 // Representación numérica si aplica
strVal string // Representación de string si aplica
anyVal any // Valor genérico (interface{})
}
)
// Cualquier valor genérico
func CreateCAny(v any) CValue {
if v == nil {
return CValue{ctype: CreateCTypeBase(BTypeAny), state: CStateNil}
}
return CValue{ctype: CreateCTypeBase(BTypeAny), anyVal: v}
}
// Booleano
func CreateCBool(v bool) CValue {
if !v {
return CValue{ctype: CreateCTypeBase(BTypeBool), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(BTypeBool), intVal: 1}
}
// Tipos enteros con funciones genéricas
func CreateCInt (v int ) CValue { return createCInts[int ](v, BTypeInt) }
func CreateCInt8 (v int8 ) CValue { return createCInts[int8 ](v, BTypeInt8) }
func CreateCInt16 (v int16 ) CValue { return createCInts[int16 ](v, BTypeInt16) }
func CreateCInt32 (v int32 ) CValue { return createCInts[int32 ](v, BTypeInt32) }
func CreateCInt64 (v int64 ) CValue { return createCInts[int64 ](v, BTypeInt64) }
// Tipos unsigned
func CreateCUint (v uint ) CValue { return createCUints[uint ](v, BTypeUint) }
func CreateCUint8 (v uint8 ) CValue { return createCUints[uint8 ](v, BTypeUint8) }
func CreateCUint16 (v uint16 ) CValue { return createCUints[uint16 ](v, BTypeUint16) }
func CreateCUint32 (v uint32 ) CValue { return createCUints[uint32 ](v, BTypeUint32) }
func CreateCUint64 (v uint64 ) CValue { return createCUints[uint64 ](v, BTypeUint64) }
func CreateCUintptr (v uintptr ) CValue { return createCUints[uintptr ](v, BTypeUintptr) }
func CreateCDuration(v Duration ) CValue { return createCUints[Duration ](v, BTypeDuration) }
func CreateCHashAlg (v HashAlg ) CValue { return createCUints[HashAlg ](v, BTypeHashAlg) }
// Tipos float
func CreateCFloat32(v float32) CValue {
if v == 0 {
return CValue{ctype: CreateCTypeBase(BTypeFloat32), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(BTypeFloat32), intVal: int64(math.Float32bits(v))}
}
func CreateCFloat64(v float64) CValue {
if v == 0 {
return CValue{ctype: CreateCTypeBase(BTypeFloat64), state: CStateZero}
}
b := math.Float64bits(v)
if b > math.MaxInt64 {
return CValue{ctype: CreateCTypeBase(BTypeFloat64), state: CStateVersion, anyVal: v}
}
return CValue{ctype: CreateCTypeBase(BTypeFloat64), intVal: int64(b)}
}
// Complejos
func CreateCComplex64 (v complex64 ) CValue { return createCCmplx[complex64 ](v, BTypeComplex64) }
func CreateCComplex128(v complex128) CValue { return createCCmplx[complex128 ](v, BTypeComplex128) }
// BigInt
func CreateCBigInt(v *BigInt) CValue {
if v.Cmp(g.bigZero) == 0 {
return CValue{ctype: CreateCTypeBase(BTypeBigInt), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(BTypeBigInt), anyVal: v}
}
// String
func CreateCString(v string) CValue {
if v == "" {
return CValue{ctype: CreateCTypeBase(BTypeString), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(BTypeString), strVal: v}
}
// Listas y estructuras similares
func CreateCBytes(v Bytes) CValue { return createCList[Bytes](v, BTypeBytes) }
func CreateCStack(v Stack) CValue { return createCList[Stack](v, BTypeStack) }
// UUID
func CreateCUUID(v UUID) CValue {
if v == g.uuidZero {
return CValue{ctype: CreateCTypeBase(BTypeUUID), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(BTypeUUID), anyVal: v}
}
// Fecha
func CreateCDate(v Date) CValue {
if v.IsZero() {
return CValue{ctype: CreateCTypeBase(BTypeDate), state: CStateZero}
}
if v.After(g.minTime) && v.Before(g.maxTime) {
return CValue{
ctype: CreateCTypeBase(BTypeDate), state: CStateVersion,
intVal: v.UnixNano(), anyVal: v.Location(),
}
}
return CValue{ctype: CreateCTypeBase(BTypeDate), anyVal: v}
}
// Tipos especiales y genéricos
func CreateCCValue(v CValue) CValue { return CValue{ctype: CreateCTypeBase(BTypeCValue), anyVal: v} }
func CreateCReflect(v reflect.Value) CValue {
if !v.IsValid() {
return CValue{ctype: CreateCTypeBase(BTypeReflect), state: CStateInvalid}
}
return CValue{ctype: CreateCTypeBase(BTypeReflect), anyVal: v}
}
// Interfaces packables
func CreateCListPackable (v ListPackable ) CValue { return createCIfcs (BTypeListPackable,v) }
func CreateCMapPackable (v MapPackable ) CValue { return createCIfcs (BTypeMapPackable ,v) }
func CreateCObjectPackable (v ObjPackable ) CValue { return createCIfcs (BTypeObjPackable ,v) }
func CreateCPackable (v Packable ) CValue { return createCIfcs (BTypePackable ,v) }
func CreateCContext (v Context ) CValue { return createCIfcs (BTypeContext ,v) }
func CreateCError (v error ) CValue { return createCIfcs (BTypeError ,v) }
func CreateCStringer (v Stringer ) CValue { return createCIfcs (BTypeStringer ,v) }
// Valores nulos o inválidos
func CreateCNil(_ any) CValue {
return CValue{ctype: CreateCTypeBase(BTypeNil), state: CStateNil}
}
func createCInvalid(_ any) CValue {
return CValue{ctype: CreateCTypeBase(BTypeInvalid), state: CStateInvalid}
}
func createCInvalidError(value any, s CState, err string) CValue {
s = CStateError | CStateInvalid
if value == nil {
s |= CStateNil
}
return CValue{ctype: CreateCTypeBase(BTypeInvalid), state: s, strVal: err, anyVal: value}
}
// Añadir o combinar un estado a un valor
func (v CValue) WithState(state CState) CValue {
v.state |= state & cStateOps
return v
}
// Funciones genéricas internas
func createCInts[T ints](v T, t BType) CValue {
if v == 0 {
return CValue{ctype: CreateCTypeBase(t), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(t), intVal: int64(v)}
}
func createCUints[T uints](v T, t BType) CValue {
if v == 0 {
return CValue{ctype: CreateCTypeBase(t), state: CStateZero}
}
if (t == BTypeUint64 || t == BTypeUintptr) && uint64(v) > math.MaxInt64 {
return CValue{ctype: CreateCTypeBase(t), state: CStateVersion, anyVal: v}
}
return CValue{ctype: CreateCTypeBase(t), intVal: int64(v)}
}
func createCCmplx[T cmplx](v T, t BType) CValue {
if v == 0 {
return CValue{ctype: CreateCTypeBase(t), state: CStateZero}
}
return CValue{ctype: CreateCTypeBase(t), anyVal: v}
}
func createCList[T lists](v T, t BType) CValue {
if v == nil {
return CValue{ctype: CreateCTypeBase(t), state: CStateNil}
}
ln := len(v)
if ln == 0 {
return CValue{ctype: CreateCTypeBase(t), state: CStateZero, anyVal: v}
}
return CValue{ctype: CreateCTypeBase(t), anyVal: v, intVal: int64(ln)}
}
// createCIfcs crea un CValue para interfaces.
// Solo detecta interfaces completamente nil (v == nil).
// La detección de punteros nil envueltos en interfaces se delega
// al programador por razones de rendimiento.
func createCIfcs(t BType, v any) CValue {
if v == nil {
return CValue{ctype: CreateCTypeBase(t), anyVal: v, state: CStateNil}
}
/*
// Código comentado: detección automática de nil envueltos
// Se omite por el costo de rendimiento de la reflection
else {
// Operación costosa: reflection para detectar valores nil
// envueltos en interfaces (ej: (*struct{})(nil) asignado a interface)
// Delegamos esta responsabilidad al programador
rv := reflect.ValueOf(v)
s |= CStateReflected
switch rv.Kind() {
case reflect.Ptr, reflect.Interface, reflect.Func, reflect.Chan, reflect.Map, reflect.Slice:
if rv.IsNil() {
s |= CStateNil
}
}
}
*/
// El programador debe de implementar las funciones IsNil específicas
// del interface (ej: IsNilError, IsNilListPackable) antes de llamar
// a esta función, o en su defecto asegurarse que el interface
// no va a ser nil.
//
// IsNilError verifica si un error interface es nil,
// incluyendo punteros nil envueltos en el interface.
/*
func IsNilError(err error) bool {
if err == nil {
return true
}
// Verifica si el valor subyacente es nil
return reflect.ValueOf(err).IsNil()
}
*/
return CValue{ctype: CreateCTypeBase(t), anyVal: v}
}

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

@ -5,4 +5,5 @@ use (
app
base
core
corx
)
Loading…
Cancel
Save

Powered by TurnKey Linux.