You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.3 KiB
52 lines
1.3 KiB
package binding
|
|
|
|
import (
|
|
"reflect"
|
|
"regexp"
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"github.com/go-kratos/kratos/v2/encoding/form"
|
|
)
|
|
|
|
var reg = regexp.MustCompile(`{[\\.\w]+}`)
|
|
|
|
// EncodeURL encode proto message to url path.
|
|
func EncodeURL(pathTemplate string, msg interface{}, needQuery bool) string {
|
|
if msg == nil || (reflect.ValueOf(msg).Kind() == reflect.Ptr && reflect.ValueOf(msg).IsNil()) {
|
|
return pathTemplate
|
|
}
|
|
queryParams, _ := form.EncodeValues(msg)
|
|
textNameQueryParams, _ := form.EncodeTextNameValues(msg)
|
|
pathParams := make(map[string]struct{})
|
|
path := reg.ReplaceAllStringFunc(pathTemplate, func(in string) string {
|
|
// it's unreachable because the reg means that must have more than one char in {}
|
|
// if len(in) < 4 { //nolint:gomnd // ** explain the 4 number here :-) **
|
|
// return in
|
|
// }
|
|
key := in[1 : len(in)-1]
|
|
pathParams[key] = struct{}{}
|
|
value := queryParams.Get(key)
|
|
if len(value) > 0 {
|
|
return value
|
|
}
|
|
return textNameQueryParams.Get(key)
|
|
})
|
|
if !needQuery {
|
|
if v, ok := msg.(proto.Message); ok {
|
|
if query := form.EncodeFieldMask(v.ProtoReflect()); query != "" {
|
|
return path + "?" + query
|
|
}
|
|
}
|
|
return path
|
|
}
|
|
if len(queryParams) > 0 {
|
|
for key := range pathParams {
|
|
delete(queryParams, key)
|
|
}
|
|
if query := queryParams.Encode(); query != "" {
|
|
path += "?" + query
|
|
}
|
|
}
|
|
return path
|
|
}
|
|
|