106 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package response
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"github.com/gin-gonic/gin/binding"
 | 
						|
	"reflect"
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	_ uint8 = iota
 | 
						|
	json
 | 
						|
	xml
 | 
						|
	yaml
 | 
						|
	form
 | 
						|
	query
 | 
						|
)
 | 
						|
 | 
						|
//var constructor = &bindConstructor{}
 | 
						|
 | 
						|
type bindConstructor struct {
 | 
						|
	cache map[string][]uint8
 | 
						|
	mux   sync.Mutex
 | 
						|
}
 | 
						|
 | 
						|
func (e *bindConstructor) GetBindingForGin(d interface{}) []binding.Binding {
 | 
						|
	bs := e.getBinding(reflect.TypeOf(d).String())
 | 
						|
	if bs == nil {
 | 
						|
		//重新构建
 | 
						|
		bs = e.resolve(d)
 | 
						|
	}
 | 
						|
	gbs := make([]binding.Binding, len(bs))
 | 
						|
	for i, b := range bs {
 | 
						|
		switch b {
 | 
						|
		case json:
 | 
						|
			gbs[i] = binding.JSON
 | 
						|
		case xml:
 | 
						|
			gbs[i] = binding.XML
 | 
						|
		case yaml:
 | 
						|
			gbs[i] = binding.YAML
 | 
						|
		case form:
 | 
						|
			gbs[i] = binding.Form
 | 
						|
		case query:
 | 
						|
			gbs[i] = binding.Query
 | 
						|
		default:
 | 
						|
			gbs[i] = nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return gbs
 | 
						|
}
 | 
						|
 | 
						|
func (e *bindConstructor) resolve(d interface{}) []uint8 {
 | 
						|
	bs := make([]uint8, 0)
 | 
						|
	qType := reflect.TypeOf(d).Elem()
 | 
						|
	var tag reflect.StructTag
 | 
						|
	var ok bool
 | 
						|
	fmt.Println(qType.Kind())
 | 
						|
	for i := 0; i < qType.NumField(); i++ {
 | 
						|
		tag = qType.Field(i).Tag
 | 
						|
		if _, ok = tag.Lookup("json"); ok {
 | 
						|
			bs = append(bs, json)
 | 
						|
		}
 | 
						|
		if _, ok = tag.Lookup("xml"); ok {
 | 
						|
			bs = append(bs, xml)
 | 
						|
		}
 | 
						|
		if _, ok = tag.Lookup("yaml"); ok {
 | 
						|
			bs = append(bs, yaml)
 | 
						|
		}
 | 
						|
		if _, ok = tag.Lookup("form"); ok {
 | 
						|
			bs = append(bs, form)
 | 
						|
		}
 | 
						|
		if _, ok = tag.Lookup("query"); ok {
 | 
						|
			bs = append(bs, query)
 | 
						|
		}
 | 
						|
		if _, ok = tag.Lookup("uri"); ok {
 | 
						|
			bs = append(bs, 0)
 | 
						|
		}
 | 
						|
		if t, ok := tag.Lookup("binding"); ok && strings.Index(t, "dive") > -1 {
 | 
						|
			qValue := reflect.ValueOf(d)
 | 
						|
			bs = append(bs, e.resolve(qValue.Field(i))...)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if t, ok := tag.Lookup("validate"); ok && strings.Index(t, "dive") > -1 {
 | 
						|
			qValue := reflect.ValueOf(d)
 | 
						|
			bs = append(bs, e.resolve(qValue.Field(i))...)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return bs
 | 
						|
}
 | 
						|
 | 
						|
func (e *bindConstructor) getBinding(name string) []uint8 {
 | 
						|
	e.mux.Lock()
 | 
						|
	defer e.mux.Unlock()
 | 
						|
	return e.cache[name]
 | 
						|
}
 | 
						|
 | 
						|
func (e *bindConstructor) setBinding(name string, bs []uint8) {
 | 
						|
	e.mux.Lock()
 | 
						|
	defer e.mux.Unlock()
 | 
						|
	if e.cache == nil {
 | 
						|
		e.cache = make(map[string][]uint8)
 | 
						|
	}
 | 
						|
	e.cache[name] = bs
 | 
						|
}
 |