summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-structr/key.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-structr/key.go')
-rw-r--r--vendor/codeberg.org/gruf/go-structr/key.go204
1 files changed, 0 insertions, 204 deletions
diff --git a/vendor/codeberg.org/gruf/go-structr/key.go b/vendor/codeberg.org/gruf/go-structr/key.go
deleted file mode 100644
index 557a5f033..000000000
--- a/vendor/codeberg.org/gruf/go-structr/key.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package structr
-
-import (
- "reflect"
- "strings"
-
- "codeberg.org/gruf/go-byteutil"
- "codeberg.org/gruf/go-mangler"
-)
-
-// KeyGen is the underlying index key generator
-// used within Index, and therefore Cache itself.
-type KeyGen[StructType any] struct {
-
- // fields contains our representation of
- // the struct fields contained in the
- // creation of keys by this generator.
- fields []structfield
-
- // zero specifies whether zero
- // value fields are permitted.
- zero bool
-}
-
-// NewKeyGen returns a new initialized KeyGen for the receiving generic
-// parameter type, comprising of the given field strings, and whether to
-// allow zero values to be included within generated output strings.
-func NewKeyGen[T any](fields []string, allowZero bool) KeyGen[T] {
- var kgen KeyGen[T]
-
- // Preallocate expected struct field slice.
- kgen.fields = make([]structfield, len(fields))
-
- // Get the reflected struct ptr type.
- t := reflect.TypeOf((*T)(nil)).Elem()
-
- for i, fieldName := range fields {
- // Split name to account for nesting.
- names := strings.Split(fieldName, ".")
-
- // Look for a usable struct field from type.
- sfield, ok := findField(t, names, allowZero)
- if !ok {
- panicf("failed finding field: %s", fieldName)
- }
-
- // Set parsed struct field.
- kgen.fields[i] = sfield
- }
-
- // Set config flags.
- kgen.zero = allowZero
-
- return kgen
-}
-
-// FromParts generates key string from individual key parts.
-func (kgen *KeyGen[T]) FromParts(parts ...any) (key string, ok bool) {
- buf := getBuf()
- if ok = kgen.AppendFromParts(buf, parts...); ok {
- key = string(buf.B)
- }
- putBuf(buf)
- return
-}
-
-// FromValue generates key string from a value, via reflection.
-func (kgen *KeyGen[T]) FromValue(value T) (key string, ok bool) {
- buf := getBuf()
- rvalue := reflect.ValueOf(value)
- if ok = kgen.appendFromRValue(buf, rvalue); ok {
- key = string(buf.B)
- }
- putBuf(buf)
- return
-}
-
-// AppendFromParts generates key string into provided buffer, from individual key parts.
-func (kgen *KeyGen[T]) AppendFromParts(buf *byteutil.Buffer, parts ...any) bool {
- if len(parts) != len(kgen.fields) {
- // User must provide correct number of parts for key.
- panicf("incorrect number key parts: want=%d received=%d",
- len(parts),
- len(kgen.fields),
- )
- }
-
- if kgen.zero {
- // Zero values are permitted,
- // mangle all values and ignore
- // zero value return booleans.
- for i, part := range parts {
-
- // Mangle this value into buffer.
- _ = kgen.fields[i].Mangle(buf, part)
-
- // Append part separator.
- buf.B = append(buf.B, '.')
- }
- } else {
- // Zero values are NOT permitted.
- for i, part := range parts {
-
- // Mangle this value into buffer.
- z := kgen.fields[i].Mangle(buf, part)
-
- if z {
- // The value was zero for
- // this type, return early.
- return false
- }
-
- // Append part separator.
- buf.B = append(buf.B, '.')
- }
- }
-
- // Drop the last separator.
- buf.B = buf.B[:len(buf.B)-1]
-
- return true
-}
-
-// AppendFromValue generates key string into provided buffer, from a value via reflection.
-func (kgen *KeyGen[T]) AppendFromValue(buf *byteutil.Buffer, value T) bool {
- return kgen.appendFromRValue(buf, reflect.ValueOf(value))
-}
-
-// appendFromRValue is the underlying generator function for the exported ___FromValue() functions,
-// accepting a reflected input. We do not expose this as the reflected value is EXPECTED to be right.
-func (kgen *KeyGen[T]) appendFromRValue(buf *byteutil.Buffer, rvalue reflect.Value) bool {
- // Follow any ptrs leading to value.
- for rvalue.Kind() == reflect.Pointer {
- rvalue = rvalue.Elem()
- }
-
- if kgen.zero {
- // Zero values are permitted,
- // mangle all values and ignore
- // zero value return booleans.
- for i := range kgen.fields {
-
- // Get the reflect value's field at idx.
- fv := rvalue.FieldByIndex(kgen.fields[i].index)
- fi := fv.Interface()
-
- // Mangle this value into buffer.
- _ = kgen.fields[i].Mangle(buf, fi)
-
- // Append part separator.
- buf.B = append(buf.B, '.')
- }
- } else {
- // Zero values are NOT permitted.
- for i := range kgen.fields {
-
- // Get the reflect value's field at idx.
- fv := rvalue.FieldByIndex(kgen.fields[i].index)
- fi := fv.Interface()
-
- // Mangle this value into buffer.
- z := kgen.fields[i].Mangle(buf, fi)
-
- if z {
- // The value was zero for
- // this type, return early.
- return false
- }
-
- // Append part separator.
- buf.B = append(buf.B, '.')
- }
- }
-
- // Drop the last separator.
- buf.B = buf.B[:len(buf.B)-1]
-
- return true
-}
-
-type structfield struct {
- // index is the reflected index
- // of this field (this takes into
- // account struct nesting).
- index []int
-
- // zero is the possible mangled
- // zero value for this field.
- zero string
-
- // mangler is the mangler function for
- // serializing values of this field.
- mangler mangler.Mangler
-}
-
-// Mangle mangles the given value, using the determined type-appropriate
-// field's type. The returned boolean indicates whether this is a zero value.
-func (f *structfield) Mangle(buf *byteutil.Buffer, value any) (isZero bool) {
- s := len(buf.B) // start pos.
- buf.B = f.mangler(buf.B, value)
- e := len(buf.B) // end pos.
- isZero = (f.zero == string(buf.B[s:e]))
- return
-}