package util import ( "reflect" ) // Implements get reflect.Zero(T) and (o).Implements(T) func Implements[T any](o any) (T, bool) { iface := reflect.TypeOf((*T)(nil)).Elem() reflectType := reflect.TypeOf(o) if alreadyReflectType, ok := o.(reflect.Type); ok { reflectType = alreadyReflectType o = reflect.Zero(reflectType).Interface() } else if alreadyReflectValue, ok := o.(reflect.Value); ok { reflectType = alreadyReflectValue.Type() o = alreadyReflectValue.Interface() } if reflectType.Implements(iface) { if reflectType.Kind() == reflect.Interface { return *reflect.New(iface).Interface().(*T), true } return o.(T), true } else { return *reflect.New(iface).Interface().(*T), false } } // PointerImplements get reflect.New(T) and (&o).Implements(T) func PointerImplements[I any](o any) (reflect.Value, bool) { iface := reflect.TypeOf((*I)(nil)).Elem() reflectType := reflect.TypeOf(&o) if alreadyReflectType, ok := o.(reflect.Type); ok { reflectType = reflect.PointerTo(alreadyReflectType) } else if alreadyReflectValue, ok := o.(reflect.Value); ok { reflectType = reflect.PointerTo(alreadyReflectValue.Type()) } reflectValue := reflect.New(reflectType.Elem()) return reflectValue, reflectType.Implements(iface) }