parent
aed26728b3
commit
4a43e5b278
@ -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
|
||||
Loading…
Reference in new issue