s3: refactor to use generated code instead of reflection to copy structs
This commit is contained in:
parent
4344a3e2ea
commit
4b981100db
3 changed files with 366 additions and 13 deletions
101
backend/s3/gen_setfrom.go
Normal file
101
backend/s3/gen_setfrom.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Generate boilerplate code for setting similar structs from each other
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
)
|
||||
|
||||
// flags
|
||||
var (
|
||||
outputFile = flag.String("o", "", "Output file name, stdout if unset")
|
||||
)
|
||||
|
||||
// globals
|
||||
var (
|
||||
out io.Writer = os.Stdout
|
||||
)
|
||||
|
||||
// genSetFrom generates code to set the public members of a from b
|
||||
//
|
||||
// a and b should be pointers to structs
|
||||
//
|
||||
// a can be a different type from b
|
||||
//
|
||||
// Only the Fields which have the same name and assignable type on a
|
||||
// and b will be set.
|
||||
//
|
||||
// This is useful for copying between almost identical structures that
|
||||
// are frequently present in auto-generated code for cloud storage
|
||||
// interfaces.
|
||||
func genSetFrom(a, b interface{}) {
|
||||
name := fmt.Sprintf("setFrom_%T_%T", a, b)
|
||||
name = strings.Replace(name, ".", "", -1)
|
||||
name = strings.Replace(name, "*", "", -1)
|
||||
fmt.Fprintf(out, "\n// %s copies matching elements from a to b\n", name)
|
||||
fmt.Fprintf(out, "func %s(a %T, b %T) {\n", name, a, b)
|
||||
ta := reflect.TypeOf(a).Elem()
|
||||
tb := reflect.TypeOf(b).Elem()
|
||||
va := reflect.ValueOf(a).Elem()
|
||||
vb := reflect.ValueOf(b).Elem()
|
||||
for i := 0; i < tb.NumField(); i++ {
|
||||
bField := vb.Field(i)
|
||||
tbField := tb.Field(i)
|
||||
name := tbField.Name
|
||||
aField := va.FieldByName(name)
|
||||
taField, found := ta.FieldByName(name)
|
||||
if found && aField.IsValid() && bField.IsValid() && aField.CanSet() && tbField.Type.AssignableTo(taField.Type) {
|
||||
fmt.Fprintf(out, "\ta.%s = b.%s\n", name, name)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(out, "}\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *outputFile != "" {
|
||||
fd, err := os.Create(*outputFile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
err := fd.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
out = fd
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, `// Code generated by "go run gen_setfrom.go"; DO NOT EDIT.
|
||||
|
||||
package s3
|
||||
|
||||
import "github.com/aws/aws-sdk-go/service/s3"
|
||||
`)
|
||||
|
||||
genSetFrom(new(s3.ListObjectsInput), new(s3.ListObjectsV2Input))
|
||||
genSetFrom(new(s3.ListObjectsV2Output), new(s3.ListObjectsOutput))
|
||||
genSetFrom(new(s3.ListObjectVersionsInput), new(s3.ListObjectsV2Input))
|
||||
genSetFrom(new(s3.ObjectVersion), new(s3.DeleteMarkerEntry))
|
||||
genSetFrom(new(s3.ListObjectsV2Output), new(s3.ListObjectVersionsOutput))
|
||||
genSetFrom(new(s3.Object), new(s3.ObjectVersion))
|
||||
genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.HeadObjectOutput))
|
||||
genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.CopyObjectInput))
|
||||
genSetFrom(new(s3.UploadPartCopyInput), new(s3.CopyObjectInput))
|
||||
genSetFrom(new(s3.HeadObjectOutput), new(s3.GetObjectOutput))
|
||||
genSetFrom(new(s3.CreateMultipartUploadInput), new(s3.PutObjectInput))
|
||||
genSetFrom(new(s3.HeadObjectOutput), new(s3.PutObjectInput))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue