todo: fix unions or remove them

This commit is contained in:
Judah Caruso 2026-01-09 16:54:20 -07:00
parent 4722e6a61f
commit 41b74c5b14

View file

@ -36,7 +36,7 @@ type anystruct any
// float32 // float32
// }) // })
type Of[T anystruct] struct { type Of[T anystruct] struct {
typ reflect.Kind typ reflect.Type
mem []byte mem []byte
} }
@ -47,39 +47,25 @@ func (u Of[T]) Size() uintptr {
// String returns the string representation of a union. // String returns the string representation of a union.
func (u Of[T]) String() string { func (u Of[T]) String() string {
var b strings.Builder var b strings.Builder
b.WriteString("union[")
if u.typ == reflect.Invalid { fmt.Fprintf(&b, "union[%s] = ", reflect.TypeFor[T]().String())
if u.typ == nil {
b.WriteString("none") b.WriteString("none")
} else { } else {
b.WriteString(u.typ.String()) b.WriteString(u.typ.String())
} }
b.WriteString("] {")
t := reflect.TypeFor[T]()
if t.Kind() == reflect.Struct {
b.WriteByte(' ')
fields := getInternalFields(u)
for i, field := range fields {
b.WriteString(field.Type.String())
if i < len(fields)-1 {
b.WriteString("; ")
}
}
b.WriteByte(' ')
}
b.WriteByte('}')
return b.String() return b.String()
} }
// Is returns true if the given type is currently stored in the union. // Is returns true if the given type is currently stored in the union.
func Is[E any, T anystruct](u Of[T]) bool { func Is[E any, T anystruct](u Of[T]) bool {
// Explicit invalid check to make sure invalid types don't result in false-positives. // Explicit invalid check to make sure invalid types don't result in false-positives.
if u.typ == reflect.Invalid { if u.typ == nil {
return false return false
} }
return u.typ == reflect.TypeFor[E]().Kind() return u.typ == reflect.TypeFor[E]()
} }
// Set overwrites the backing memory of a union with the given value; initializing the union if uninitialized. // Set overwrites the backing memory of a union with the given value; initializing the union if uninitialized.
@ -91,8 +77,8 @@ func Set[V any, T anystruct](u *Of[T], value V) {
u.mem = make([]byte, mem.Sizeof[T]()) u.mem = make([]byte, mem.Sizeof[T]())
} }
*(*V)(unsafe.Pointer(&u.mem[0])) = value unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0] = value
u.typ = reflect.TypeFor[V]().Kind() u.typ = reflect.TypeFor[V]()
} }
// SetSafe overwrites the backing memory of a union with the given value, // SetSafe overwrites the backing memory of a union with the given value,
@ -107,8 +93,8 @@ func SetSafe[V any, T anystruct](u *Of[T], value V) error {
vt := reflect.TypeFor[V]() vt := reflect.TypeFor[V]()
for _, field := range getInternalFields(*u) { for _, field := range getInternalFields(*u) {
if field.Type == vt { if field.Type == vt {
*(*V)(unsafe.Pointer(&u.mem[0])) = value unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0] = value
u.typ = reflect.TypeFor[V]().Kind() u.typ = reflect.TypeFor[V]()
return nil return nil
} }
} }
@ -125,7 +111,7 @@ func Get[V any, T anystruct](u Of[T]) V {
panic(ErrUninitializedAccess) panic(ErrUninitializedAccess)
} }
return *(*V)(unsafe.Pointer(&u.mem[0])) return unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0]
} }
// GetSafe returns the union's backing memory interpreted as a value of type V, returning an error if the type // GetSafe returns the union's backing memory interpreted as a value of type V, returning an error if the type
@ -140,7 +126,7 @@ func GetSafe[V any, T anystruct](u Of[T]) (V, error) {
vt := reflect.TypeFor[V]() vt := reflect.TypeFor[V]()
for _, field := range getInternalFields(u) { for _, field := range getInternalFields(u) {
if field.Type == vt { if field.Type == vt {
return *(*V)(unsafe.Pointer(&u.mem[0])), nil return unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0], nil
} }
} }