diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mangler/v2/struct.go')
| -rw-r--r-- | vendor/codeberg.org/gruf/go-mangler/v2/struct.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-mangler/v2/struct.go b/vendor/codeberg.org/gruf/go-mangler/v2/struct.go new file mode 100644 index 000000000..e9672bf2b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-mangler/v2/struct.go @@ -0,0 +1,75 @@ +package mangler + +import ( + "unsafe" + + "codeberg.org/gruf/go-xunsafe" +) + +// field stores the minimum necessary +// data for iterating and mangling +// each field in a given struct. +type field struct { + mangle Mangler + offset uintptr +} + +// iterStructType returns a Mangler capable of iterating +// and mangling the given struct type currently in TypeIter{}. +// note this will fetch sub-Manglers for each struct field. +func iterStructType(t xunsafe.TypeIter) Mangler { + + // Number of struct fields. + n := t.Type.NumField() + + // Gather mangler functions. + fields := make([]field, n) + for i := 0; i < n; i++ { + + // Get struct field at index. + sfield := t.Type.Field(i) + rtype := sfield.Type + + // Get nested field TypeIter with appropriate flags. + flags := xunsafe.ReflectStructFieldFlags(t.Flag, rtype) + ft := t.Child(sfield.Type, flags) + + // Get field mangler. + fn := loadOrGet(ft) + if fn == nil { + return nil + } + + // Set field info. + fields[i] = field{ + mangle: fn, + offset: sfield.Offset, + } + } + + // Handle no. fields. + switch len(fields) { + case 0: + return empty_mangler + case 1: + return fields[0].mangle + default: + return func(buf []byte, ptr unsafe.Pointer) []byte { + for i := range fields { + // Get struct field ptr via offset. + fptr := add(ptr, fields[i].offset) + + // Mangle the struct field data. + buf = fields[i].mangle(buf, fptr) + buf = append(buf, ',') + } + + if len(fields) > 0 { + // Drop final comma. + buf = buf[:len(buf)-1] + } + + return buf + } + } +} |
