165 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			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
 | 
						|
}
 |