diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mangler/load.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-mangler/load.go | 158 |
1 files changed, 57 insertions, 101 deletions
diff --git a/vendor/codeberg.org/gruf/go-mangler/load.go b/vendor/codeberg.org/gruf/go-mangler/load.go index c4d94cd7e..bc79d381e 100644 --- a/vendor/codeberg.org/gruf/go-mangler/load.go +++ b/vendor/codeberg.org/gruf/go-mangler/load.go @@ -6,9 +6,11 @@ import ( // loadMangler is the top-most Mangler load function. It guarantees that a Mangler // function will be returned for given value interface{} and reflected type. Else panics. -func loadMangler(a any, t reflect.Type) Mangler { +func loadMangler(t reflect.Type) Mangler { + ctx := typecontext{rtype: t} + // Load mangler fn - mng := load(a, t) + mng := load(ctx) if mng != nil { return mng } @@ -19,31 +21,14 @@ func loadMangler(a any, t reflect.Type) Mangler { // load will load a Mangler or reflect Mangler for given type and iface 'a'. // Note: allocates new interface value if nil provided, i.e. if coming via reflection. -func load(a any, t reflect.Type) Mangler { - if t == nil { +func load(ctx typecontext) Mangler { + if ctx.rtype == nil { // There is no reflect type to search by panic("cannot mangle nil interface{} type") } - if a == nil { - // Alloc new iface instance - v := reflect.New(t).Elem() - a = v.Interface() - } - - // Check for Mangled implementation. - if _, ok := a.(Mangled); ok { - return mangle_mangled - } - - // Search mangler by reflection. - mng := loadReflect(t) - if mng != nil { - return mng - } - - // Prefer iface mangler. - mng = loadIface(a) + // Search by reflection. + mng := loadReflect(ctx) if mng != nil { return mng } @@ -51,46 +36,24 @@ func load(a any, t reflect.Type) Mangler { return nil } -// loadIface is used as a near-last-resort interface{} type switch -// loader for types implementating other known (slower) functions. -func loadIface(a any) Mangler { - switch a.(type) { - case binarymarshaler: - return mangle_binary - case byteser: - return mangle_byteser - case stringer: - return mangle_stringer - case textmarshaler: - return mangle_text - case jsonmarshaler: - return mangle_json - default: - return nil - } -} - // loadReflect will load a Mangler (or rMangler) function for the given reflected type info. // NOTE: this is used as the top level load function for nested reflective searches. -func loadReflect(t reflect.Type) Mangler { - switch t.Kind() { +func loadReflect(ctx typecontext) Mangler { + switch ctx.rtype.Kind() { case reflect.Pointer: - return loadReflectPtr(t) + return loadReflectPtr(ctx) case reflect.String: return mangle_string case reflect.Struct: - return loadReflectStruct(t) + return loadReflectStruct(ctx) case reflect.Array: - return loadReflectArray(t) + return loadReflectArray(ctx) case reflect.Slice: - return loadReflectSlice(t) - - case reflect.Map: - return loadReflectMap(t) + return loadReflectSlice(ctx) case reflect.Bool: return mangle_bool @@ -98,7 +61,7 @@ func loadReflect(t reflect.Type) Mangler { case reflect.Int, reflect.Uint, reflect.Uintptr: - return mangle_platform_int() + return mangle_int case reflect.Int8, reflect.Uint8: return mangle_8bit @@ -131,21 +94,18 @@ func loadReflect(t reflect.Type) Mangler { // loadReflectPtr loads a Mangler (or rMangler) function for a ptr's element type. // This also handles further dereferencing of any further ptr indrections (e.g. ***int). -func loadReflectPtr(t reflect.Type) Mangler { - var count int - - // Elem - et := t +func loadReflectPtr(ctx typecontext) Mangler { + var n uint // Iteratively dereference ptrs - for et.Kind() == reflect.Pointer { - et = et.Elem() - count++ + for ctx.rtype.Kind() == reflect.Pointer { + ctx.rtype = ctx.rtype.Elem() + n++ } - // Search for ptr elemn type mangler. - if mng := load(nil, et); mng != nil { - return deref_ptr_mangler(et, mng, count) + // Search for elemn type mangler. + if mng := load(ctx); mng != nil { + return deref_ptr_mangler(ctx, mng, n) } return nil @@ -153,8 +113,8 @@ func loadReflectPtr(t reflect.Type) Mangler { // loadReflectKnownSlice loads a Mangler function for a // known slice-of-element type (in this case, primtives). -func loadReflectKnownSlice(et reflect.Type) Mangler { - switch et.Kind() { +func loadReflectKnownSlice(ctx typecontext) Mangler { + switch ctx.rtype.Kind() { case reflect.String: return mangle_string_slice @@ -164,7 +124,7 @@ func loadReflectKnownSlice(et reflect.Type) Mangler { case reflect.Int, reflect.Uint, reflect.Uintptr: - return mangle_platform_int_slice() + return mangle_int_slice case reflect.Int8, reflect.Uint8: return mangle_8bit_slice @@ -196,64 +156,60 @@ func loadReflectKnownSlice(et reflect.Type) Mangler { } // loadReflectSlice ... -func loadReflectSlice(t reflect.Type) Mangler { - // Element type - et := t.Elem() +func loadReflectSlice(ctx typecontext) Mangler { + // Set nesting type. + ctx.ntype = ctx.rtype + + // Get nested element type. + ctx.rtype = ctx.rtype.Elem() // Preferably look for known slice mangler func - if mng := loadReflectKnownSlice(et); mng != nil { + if mng := loadReflectKnownSlice(ctx); mng != nil { return mng } - // Fallback to nested mangler iteration. - if mng := load(nil, et); mng != nil { - return iter_slice_mangler(t, mng) + // Use nested mangler iteration. + if mng := load(ctx); mng != nil { + return iter_slice_mangler(ctx, mng) } return nil } // loadReflectArray ... -func loadReflectArray(t reflect.Type) Mangler { - // Element type. - et := t.Elem() +func loadReflectArray(ctx typecontext) Mangler { + // Set nesting type. + ctx.ntype = ctx.rtype - // Use manglers for nested iteration. - if mng := load(nil, et); mng != nil { - return iter_array_mangler(t, mng) - } - - return nil -} - -// loadReflectMap ... -func loadReflectMap(t reflect.Type) Mangler { - // Map types. - kt := t.Key() - et := t.Elem() - - // Load manglers. - kmng := load(nil, kt) - emng := load(nil, et) + // Get nested element type. + ctx.rtype = ctx.rtype.Elem() // Use manglers for nested iteration. - if kmng != nil && emng != nil { - return iter_map_mangler(t, kmng, emng) + if mng := load(ctx); mng != nil { + return iter_array_mangler(ctx, mng) } return nil } // loadReflectStruct ... -func loadReflectStruct(t reflect.Type) Mangler { +func loadReflectStruct(ctx typecontext) Mangler { var mngs []Mangler + // Set nesting type. + ctx.ntype = ctx.rtype + // Gather manglers for all fields. - for i := 0; i < t.NumField(); i++ { - field := t.Field(i) + for i := 0; i < ctx.ntype.NumField(); i++ { + + // Field typectx. + ctx := typecontext{ + ntype: ctx.ntype, + rtype: ctx.ntype.Field(i).Type, + } - // Load mangler for field type. - mng := load(nil, field.Type) + // Load mangler. + mng := load(ctx) if mng == nil { return nil } @@ -263,5 +219,5 @@ func loadReflectStruct(t reflect.Type) Mangler { } // Use manglers for nested iteration. - return iter_struct_mangler(t, mngs) + return iter_struct_mangler(ctx, mngs) } |