structmapper/api.go

67 lines
1.6 KiB
Go

package structmapper
import (
"encoding/json"
"fmt"
"reflect"
di "git.apihub24.de/admin/generic-di"
"git.apihub24.de/admin/structmapper/utils"
)
func RegisterStrategy[TFrom any, TTo any](mapper func(TFrom) (TTo, error)) {
registry := di.Inject[*mapperRegistry]()
key := fmt.Sprintf("%s_%s", utils.GetName[TFrom](), utils.GetName[TTo]())
registry.RegisterStrategy(key, func(from any) (any, error) {
parsedFrom := from.(TFrom)
return mapper(parsedFrom)
})
}
func UnregisterStrategy[TFrom any, TTo any]() {
registry := di.Inject[*mapperRegistry]()
key := fmt.Sprintf("%s_%s", utils.GetName[TFrom](), utils.GetName[TTo]())
registry.UnregisterStrategy(key)
}
func Map[TFrom any, TTo any](from TFrom) (TTo, error) {
registry := di.Inject[*mapperRegistry]()
key := fmt.Sprintf("%s_%s", utils.GetName[TFrom](), utils.GetName[TTo]())
tmp, err := registry.Run(key, from)
if MappingStrategyNotFound.IsSameAs(err) {
return AutoMap[TFrom, TTo](from)
}
if err != nil {
var def TTo
return def, err
}
result := tmp.(TTo)
return result, err
}
func SliceMap[TFrom any, TTo any](from []TFrom) []TTo {
var err error
var rTo = make([]TTo, len(from))
for idx, rFrom := range from {
rTo[idx], err = Map[TFrom, TTo](rFrom)
if err != nil {
return make([]TTo, 0)
}
}
return rTo
}
func AutoMap[TFrom any, TTo any](from TFrom) (TTo, error) {
var result TTo
resultValue := reflect.ValueOf(&result).Elem()
if resultValue.Kind() == reflect.Ptr {
resultValue.Set(reflect.New(resultValue.Type().Elem()))
}
str, err := json.Marshal(from)
if err != nil {
return result, err
}
err = json.Unmarshal(str, resultValue.Addr().Interface())
return result, err
}