func TestCanSetIdempotencyToken(t *testing.T) { cases := []struct { CanSet bool Case interface{} }{ { true, struct { Field *string `idempotencyToken:"true"` }{}, }, { true, struct { Field string `idempotencyToken:"true"` }{}, }, { false, struct { Field *string `idempotencyToken:"true"` }{Field: new(string)}, }, { false, struct { Field string `idempotencyToken:"true"` }{Field: "value"}, }, { false, struct { Field *int `idempotencyToken:"true"` }{}, }, { false, struct { Field *string }{}, }, } for i, c := range cases { v := reflect.Indirect(reflect.ValueOf(c.Case)) ty := v.Type() canSet := protocol.CanSetIdempotencyToken(v.Field(0), ty.Field(0)) assert.Equal(t, c.CanSet, canSet, "Expect case %d can set to match", i) } }
func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error { if !value.IsValid() { return nil } t := value.Type() for i := 0; i < value.NumField(); i++ { elemValue := elemOf(value.Field(i)) field := t.Field(i) if field.PkgPath != "" { continue // ignore unexported fields } if protocol.CanSetIdempotencyToken(value.Field(i), field) { token := protocol.GetIdempotencyToken() elemValue = reflect.ValueOf(token) } var name string if q.isEC2 { name = field.Tag.Get("queryName") } if name == "" { if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { name = field.Tag.Get("locationNameList") } else if locName := field.Tag.Get("locationName"); locName != "" { name = locName } if name != "" && q.isEC2 { name = strings.ToUpper(name[0:1]) + name[1:] } } if name == "" { name = field.Name } if prefix != "" { name = prefix + "." + name } if err := q.parseValue(v, elemValue, name, field.Tag); err != nil { return err } } return nil }
// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested // types are converted to XMLNodes also. func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { if !value.IsValid() { return nil } fieldAdded := false // unwrap payloads if payload := tag.Get("payload"); payload != "" { field, _ := value.Type().FieldByName(payload) tag = field.Tag value = elemOf(value.FieldByName(payload)) if !value.IsValid() { return nil } } child := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) // there is an xmlNamespace associated with this struct if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" { ns := xml.Attr{ Name: xml.Name{Local: "xmlns"}, Value: uri, } if prefix != "" { b.namespaces[prefix] = uri // register the namespace ns.Name.Local = "xmlns:" + prefix } child.Attr = append(child.Attr, ns) } t := value.Type() for i := 0; i < value.NumField(); i++ { member := elemOf(value.Field(i)) field := t.Field(i) if field.PkgPath != "" { continue // ignore unexported fields } mTag := field.Tag if mTag.Get("location") != "" { // skip non-body members continue } if protocol.CanSetIdempotencyToken(value.Field(i), field) { token := protocol.GetIdempotencyToken() member = reflect.ValueOf(token) } memberName := mTag.Get("locationName") if memberName == "" { memberName = field.Name mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) } if err := b.buildValue(member, child, mTag); err != nil { return err } fieldAdded = true } if fieldAdded { // only append this child if we have one ore more valid members current.AddChild(child) } return nil }
func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { if !value.IsValid() { return nil } // unwrap payloads if payload := tag.Get("payload"); payload != "" { field, _ := value.Type().FieldByName(payload) tag = field.Tag value = elemOf(value.FieldByName(payload)) if !value.IsValid() { return nil } } buf.WriteByte('{') t := value.Type() first := true for i := 0; i < t.NumField(); i++ { member := value.Field(i) field := t.Field(i) if field.PkgPath != "" { continue // ignore unexported fields } if field.Tag.Get("json") == "-" { continue } if field.Tag.Get("location") != "" { continue // ignore non-body elements } if protocol.CanSetIdempotencyToken(member, field) { token := protocol.GetIdempotencyToken() member = reflect.ValueOf(&token) } if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { continue // ignore unset fields } if first { first = false } else { buf.WriteByte(',') } // figure out what this field is called name := field.Name if locName := field.Tag.Get("locationName"); locName != "" { name = locName } fmt.Fprintf(buf, "%q:", name) err := buildAny(member, buf, field.Tag) if err != nil { return err } } buf.WriteString("}") return nil }