gen_setfrom.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Generate boilerplate code for setting similar structs from each other
  2. //go:build ignore
  3. package main
  4. import (
  5. "flag"
  6. "fmt"
  7. "io"
  8. "log"
  9. "os"
  10. "reflect"
  11. "strings"
  12. "github.com/aws/aws-sdk-go-v2/service/s3"
  13. "github.com/aws/aws-sdk-go-v2/service/s3/types"
  14. )
  15. // flags
  16. var (
  17. outputFile = flag.String("o", "", "Output file name, stdout if unset")
  18. )
  19. // globals
  20. var (
  21. out io.Writer = os.Stdout
  22. )
  23. // genSetFrom generates code to set the public members of a from b
  24. //
  25. // a and b should be pointers to structs
  26. //
  27. // a can be a different type from b
  28. //
  29. // Only the Fields which have the same name and assignable type on a
  30. // and b will be set.
  31. //
  32. // This is useful for copying between almost identical structures that
  33. // are frequently present in auto-generated code for cloud storage
  34. // interfaces.
  35. func genSetFrom(a, b interface{}) {
  36. name := fmt.Sprintf("setFrom_%T_%T", a, b)
  37. name = strings.Replace(name, ".", "", -1)
  38. name = strings.Replace(name, "*", "", -1)
  39. fmt.Fprintf(out, "\n// %s copies matching elements from a to b\n", name)
  40. fmt.Fprintf(out, "func %s(a %T, b %T) {\n", name, a, b)
  41. ta := reflect.TypeOf(a).Elem()
  42. tb := reflect.TypeOf(b).Elem()
  43. va := reflect.ValueOf(a).Elem()
  44. vb := reflect.ValueOf(b).Elem()
  45. for i := 0; i < tb.NumField(); i++ {
  46. bField := vb.Field(i)
  47. tbField := tb.Field(i)
  48. name := tbField.Name
  49. aField := va.FieldByName(name)
  50. taField, found := ta.FieldByName(name)
  51. if found && aField.IsValid() && bField.IsValid() && aField.CanSet() && tbField.Type.AssignableTo(taField.Type) {
  52. fmt.Fprintf(out, "\ta.%s = b.%s\n", name, name)
  53. }
  54. }
  55. fmt.Fprintf(out, "}\n")
  56. }
  57. func main() {
  58. flag.Parse()
  59. if *outputFile != "" {
  60. fd, err := os.Create(*outputFile)
  61. if err != nil {
  62. log.Fatal(err)
  63. }
  64. defer func() {
  65. err := fd.Close()
  66. if err != nil {
  67. log.Fatal(err)
  68. }
  69. }()
  70. out = fd
  71. }
  72. fmt.Fprintf(out, `// Code generated by "go run gen_setfrom.go"; DO NOT EDIT.
  73. package s3
  74. import (
  75. "github.com/aws/aws-sdk-go-v2/service/s3"
  76. "github.com/aws/aws-sdk-go-v2/service/s3/types"
  77. )
  78. `)
  79. genSetFrom(new(s3.ListObjectsInput), new(s3.ListObjectsV2Input))
  80. genSetFrom(new(s3.ListObjectsV2Output), new(s3.ListObjectsOutput))
  81. genSetFrom(new(s3.ListObjectVersionsInput), new(s3.ListObjectsV2Input))
  82. genSetFrom(new(types.ObjectVersion), new(types.DeleteMarkerEntry))
  83. genSetFrom(new(s3.ListObjectsV2Output), new(s3.ListObjectVersionsOutput))
  84. genSetFrom(new(types.Object), new(types.ObjectVersion))
  85. genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.HeadObjectOutput))
  86. genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.CopyObjectInput))
  87. genSetFrom(new(s3.UploadPartCopyInput), new(s3.CopyObjectInput))
  88. genSetFrom(new(s3.HeadObjectOutput), new(s3.GetObjectOutput))
  89. genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.PutObjectInput))
  90. genSetFrom(new(s3.HeadObjectOutput), new(s3.PutObjectInput))
  91. genSetFrom(new(s3.CopyObjectInput), new(s3.PutObjectInput))
  92. }