in oss/client.go [785:906]
func (c *Client) marshalInput(request any, input *OperationInput, handlers ...func(any, *OperationInput) error) error {
// merge common fields
if cm, ok := request.(RequestCommonInterface); ok {
h, p, b := cm.GetCommonFileds()
// headers
if len(h) > 0 {
if input.Headers == nil {
input.Headers = map[string]string{}
}
for k, v := range h {
input.Headers[k] = v
}
}
// parameters
if len(p) > 0 {
if input.Parameters == nil {
input.Parameters = map[string]string{}
}
for k, v := range p {
input.Parameters[k] = v
}
}
// body
input.Body = b
}
val := reflect.ValueOf(request)
switch val.Kind() {
case reflect.Pointer, reflect.Interface:
if val.IsNil() {
return nil
}
val = val.Elem()
}
if val.Kind() != reflect.Struct || input == nil {
return nil
}
t := val.Type()
for k := 0; k < t.NumField(); k++ {
if tag, ok := t.Field(k).Tag.Lookup("input"); ok {
// header|query|body,filed_name,[required,time,usermeta...]
v := val.Field(k)
var flags int = 0
tokens := strings.Split(tag, ",")
if len(tokens) < 2 {
continue
}
// parse field flags
if len(tokens) > 2 {
flags = parseFiledFlags(tokens[2:])
}
// check required flag
if isEmptyValue(v) {
if flags&fRequire != 0 {
return NewErrParamRequired(t.Field(k).Name)
}
continue
}
switch tokens[0] {
case "query":
if input.Parameters == nil {
input.Parameters = map[string]string{}
}
if v.Kind() == reflect.Pointer {
v = v.Elem()
}
input.Parameters[tokens[1]] = fmt.Sprintf("%v", v.Interface())
case "header":
if input.Headers == nil {
input.Headers = map[string]string{}
}
if v.Kind() == reflect.Pointer {
v = v.Elem()
}
if flags&fTypeUsermeta != 0 {
if m, ok := v.Interface().(map[string]string); ok {
for k, v := range m {
input.Headers[tokens[1]+k] = v
}
}
} else {
input.Headers[tokens[1]] = fmt.Sprintf("%v", v.Interface())
}
case "body":
if flags&fTypeXml != 0 {
var b bytes.Buffer
if err := xml.NewEncoder(&b).EncodeElement(
v.Interface(),
xml.StartElement{Name: xml.Name{Local: tokens[1]}}); err != nil {
return &SerializationError{
Err: err,
}
}
input.Body = bytes.NewReader(b.Bytes())
} else {
if r, ok := v.Interface().(io.Reader); ok {
input.Body = r
} else {
return NewErrParamTypeNotSupport(t.Field(k).Name)
}
}
}
}
}
if err := validateInput(input); err != nil {
return err
}
for _, h := range handlers {
if err := h(request, input); err != nil {
return err
}
}
return nil
}