Files
ozon-api-client/core.go
2024-01-29 23:22:57 +03:00

165 lines
3.2 KiB
Go

package core
import (
"fmt"
"net/http"
"reflect"
"strconv"
"testing"
"time"
)
type CommonResponse struct {
StatusCode int
Code int `json:"code"`
Details []CommonResponseDetail `json:"details"`
Message string `json:"message"`
}
type CommonResponseDetail struct {
TypeUrl string `json:"typeUrl"`
Value string `json:"value"`
}
type Response struct {
CommonResponse
Data interface{}
}
func (r Response) CopyCommonResponse(rhs *CommonResponse) {
rhs.Code = r.Code
rhs.Details = r.Details
rhs.StatusCode = r.StatusCode
rhs.Message = r.Message
}
func getDefaultValues(v reflect.Value) error {
vValue := v.Elem()
vType := vValue.Type()
for i := 0; i < vType.NumField(); i++ {
field := vType.Field(i)
switch field.Type.Kind() {
case reflect.Slice:
for j := 0; j < vValue.Field(i).Len(); j++ {
// skip if slice type is primitive
if vValue.Field(i).Index(j).Kind() != reflect.Struct {
continue
}
// Attach any slices as query params
err := getDefaultValues(vValue.Field(i).Index(j).Addr())
if err != nil {
return err
}
}
case reflect.String:
isNil, err := isZero(vValue.Field(i).Addr())
if err != nil {
return err
}
if !isNil {
continue
}
defaultValue, ok := field.Tag.Lookup("default")
if !ok {
continue
}
vValue.Field(i).SetString(defaultValue)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
isNil, err := isZero(vValue.Field(i).Addr())
if err != nil {
return err
}
if !isNil {
continue
}
defaultValue, ok := field.Tag.Lookup("default")
if !ok {
continue
}
defaultValueInt, err := strconv.Atoi(defaultValue)
if err != nil {
return err
}
vValue.Field(i).SetInt(int64(defaultValueInt))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
isNil, err := isZero(vValue.Field(i).Addr())
if err != nil {
return err
}
if !isNil {
continue
}
defaultValue, ok := field.Tag.Lookup("default")
if !ok {
continue
}
defaultValueUint, err := strconv.ParseUint(defaultValue, 10, 64)
if err != nil {
return err
}
vValue.Field(i).SetUint(uint64(defaultValueUint))
case reflect.Struct:
err := getDefaultValues(vValue.Field(i).Addr())
if err != nil {
return err
}
case reflect.Ptr:
isNil, err := isZero(vValue.Field(i).Addr())
if err != nil {
return err
}
if isNil {
continue
}
if err := getDefaultValues(vValue.Field(i)); err != nil {
return err
}
default:
continue
}
}
return nil
}
func buildRawQuery(req *http.Request, v interface{}) (string, error) {
query := req.URL.Query()
if v == nil {
return query.Encode(), nil
}
err := getDefaultValues(reflect.ValueOf(v))
if err != nil {
return "", err
}
return query.Encode(), nil
}
func isZero(v reflect.Value) (bool, error) {
t := v.Elem().Type()
if !t.Comparable() {
return false, fmt.Errorf("type is not comparable: %v", t)
}
return reflect.Zero(t).Equal(v.Elem()), nil
}
func TimeFromString(t *testing.T, format, datetime string) time.Time {
dt, err := time.Parse(format, datetime)
if err != nil {
t.Errorf("error when parsing time: %s", err)
}
return dt
}