payload.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package rest
  2. import "reflect"
  3. // PayloadMember returns the payload field member of i if there is one, or nil.
  4. func PayloadMember(i interface{}) interface{} {
  5. if i == nil {
  6. return nil
  7. }
  8. v := reflect.ValueOf(i).Elem()
  9. if !v.IsValid() {
  10. return nil
  11. }
  12. if field, ok := v.Type().FieldByName("_"); ok {
  13. if payloadName := field.Tag.Get("payload"); payloadName != "" {
  14. field, _ := v.Type().FieldByName(payloadName)
  15. if field.Tag.Get("type") != "structure" {
  16. return nil
  17. }
  18. payload := v.FieldByName(payloadName)
  19. if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) {
  20. return payload.Interface()
  21. }
  22. }
  23. }
  24. return nil
  25. }
  26. const nopayloadPayloadType = "nopayload"
  27. // PayloadType returns the type of a payload field member of i if there is one,
  28. // or "".
  29. func PayloadType(i interface{}) string {
  30. v := reflect.Indirect(reflect.ValueOf(i))
  31. if !v.IsValid() {
  32. return ""
  33. }
  34. if field, ok := v.Type().FieldByName("_"); ok {
  35. if noPayload := field.Tag.Get(nopayloadPayloadType); noPayload != "" {
  36. return nopayloadPayloadType
  37. }
  38. if payloadName := field.Tag.Get("payload"); payloadName != "" {
  39. if member, ok := v.Type().FieldByName(payloadName); ok {
  40. return member.Tag.Get("type")
  41. }
  42. }
  43. }
  44. return ""
  45. }