You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
6.8 KiB

/* ——————————————————————————————————————————————————————————————————————————
Proyecto goat
—————————————————————————————————————————————————————————————————————————————
Fichero spec.go
Package cvls
Autor Juan V. Navarro juanvnl@activething.com
Creado 05/02/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
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 NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/goat
git : g.activething.com | github.com/activething/goat
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package cvls
const (
specSimpleMaxBits = 6
specCompoundMaxBits = 2
// Máscaras para extraer los bits en Spec
specValueMask Spec = 0x003F // 6 bits (0-5)
specCompMask Spec = 0x00C0 // 2 bits (6-7)
specKeyMask Spec = 0x3F00 // 6 bits (8-13)
// Desplazamientos (solo para creación, no para lectura)
specCompoundShift = specSimpleMaxBits
valueTypeShift = 0
specKeyShift = specCompoundShift + specCompoundMaxBits
)
const (
invalidSpec = "invalid"
)
const (
// Tipos compuestos (2 bits, alineados con bits 6-7)
SpecScalar Spec = 0 << specCompoundShift // 0x0000
SpecDefer Spec = 1 << specCompoundShift // 0x0040
SpecList Spec = 2 << specCompoundShift // 0x0080
SpecMap Spec = 3 << specCompoundShift // 0x00C0
specCompoundMax = 4
)
type Spec uint16
// Funciones de creación
// MakeSpecScalar creates a Spec for a scalar value with the specified base type.
// Returns Spec(KindInvalid) if ctyp is invalid (KindInvalid or >= maxKind).
func MakeSpecScalar(kind Kind) (Spec, bool) {
if kind >= maxKind {
return Spec(KindAny), false
}
return Spec(kind), true
}
func makeSpecScalar(kind Kind) Spec { return Spec(kind) }
// MakeSpecList creates a Spec for a list with the specified base type.
// Returns Spec(KindInvalid) if ctyp is invalid (KindInvalid or >= maxKind).
func MakeSpecList(kind Kind) (Spec, bool) {
if kind >= maxKind {
return Spec(KindAny), false
}
return Spec(kind) | SpecList, true
}
func makeSpecList(kind Kind) Spec {
return Spec(kind) | SpecList
}
// MakeSpecMap creates a Spec for a map with the specified value and key types.
// Returns Spec(KindInvalid) if ctyp or ktyp is invalid (KindInvalid or >= maxKind).
func MakeSpecMap(kind, keyKind Kind) (Spec, bool) {
if kind >= maxKind || keyKind >= maxKind {
return Spec(KindAny), false
}
return Spec(kind) | (Spec(keyKind) << specKeyShift) | SpecMap, true
}
func makeSpecMap(kind, ktype Kind) Spec {
return Spec(kind) | (Spec(ktype) << specKeyShift) | SpecMap
}
// MakeSpecDefer creates a Spec for a deferred value with the specified base type.
// Returns Spec(KindInvalid) if ctyp is invalid (KindInvalid or >= maxKind).
func MakeSpecDefer(kind Kind) (Spec, bool) {
if kind >= maxKind {
return Spec(KindAny), false
}
return Spec(kind) | SpecDefer, true
}
func makeSpecDefer(kind Kind) Spec {
return Spec(kind) | SpecDefer
}
// Métodos para Spec
func (t Spec) ValueKind() Kind { return Kind(t & specValueMask) }
func (t Spec) KeyKind() Kind { return Kind((t & specKeyMask) >> specKeyShift) }
func (t Spec) DataType() Spec { return t & specCompMask }
func (t Spec) IsScalar() bool { return (t & specCompMask) == SpecScalar }
func (t Spec) IsDefer() bool { return (t & specCompMask) == SpecDefer }
func (t Spec) IsMap() bool { return (t & specCompMask) == SpecMap }
func (t Spec) IsList() bool { return (t & specCompMask) == SpecList }
func (t Spec) IsValid() bool {
valueType := Kind(t & specValueMask)
if valueType >= maxKind {
return false
}
switch t & specCompMask {
case SpecScalar, SpecDefer, SpecList:
return t&specKeyMask == 0
case SpecMap:
keyType := Kind((t & specKeyMask) >> specKeyShift)
return keyType < maxKind
default:
return false
}
}
func (t Spec) String() string {
if !t.IsValid() {
return invalidSpec
}
c := t & specCompMask
i := 0
switch c {
// case SpecScalar: : i = 0
case SpecDefer:
i = 1
case SpecList:
i = 2
case SpecMap:
i = 3
default:
return invalidSpec
}
var buf [64]byte
b := buf[:0]
b = append(b, specNames[i]...)
b = append(b, '|')
if c == SpecMap {
b = append(b, t.KeyKind().String()...)
b = append(b, '@')
}
b = append(b, t.ValueKind().String()...)
return string(b)
}

Powered by TurnKey Linux.