package rest import ( "io" "log" "reflect" "strings" "git.ali33.ru/fcg-xvii/go-tools/json" ) func findFileKey(m map[string]io.ReadCloser, key string) (io.Reader, bool) { key = camelToSnake(key) for fKey, val := range m { fKey = strings.Replace(fKey, ".", "_", -1) if key == fKey { return val, true } } return nil, false } func findKey(m map[string]any, key string) (val any, check bool) { if val, check = m[key]; !check { if !check { key = camelToSnake(key) val, check = m[key] } } return val, check } func serializeRequest(obj any, data json.Map, files map[string]io.ReadCloser, parent string) IErrorArgs { data.LogPretty() val := reflect.ValueOf(obj) if val.Kind() != reflect.Ptr { return NewErrPrtexpected(parent) } el := val.Elem() for i := 0; i < el.NumField(); i++ { required, isFile, arrived := false, false, false field := el.Type().Field(i) log.Println("------>", field) xField := el.Field(i) tag := field.Tag.Get("rest") if len(tag) > 0 { required = strings.Contains(tag, "required") isFile = strings.Contains(tag, "file") } if isFile { if f, check := findFileKey(files, field.Name); check { xField.Set(reflect.ValueOf(f)) arrived = true } } else { if cval, check := findKey(data, field.Name); check { rVal := reflect.ValueOf(cval) switch { case xField.Kind() == reflect.Ptr: if rVal.Kind() != reflect.Map { return NewErrFieldType(field.Name, xField.Type().String(), rVal.String(), "expected json object") } rv := reflect.New(xField.Type().Elem()) m := rVal.Convert(reflect.TypeOf(json.Map{})).Interface() if err := serializeRequest(rv.Interface(), m.(json.Map), files, field.Name); err != nil { return err } xField.Set(rv) default: if rVal.CanConvert(xField.Type()) { xField.Set(rVal.Convert(xField.Type())) } else { return NewErrFieldType(field.Name, xField.Type().String(), rVal.Kind().String(), "convert error") } } arrived = true } } if required && !arrived { return NewErrFieldRequired(field.Name) } } return nil }