| package main |
| |
| import ( |
| "fmt" |
| "strings" |
| "text/template" |
| "time" |
| ) |
| |
| func printArgs(args []fnArg) string { |
| var argStr []string |
| for _, arg := range args { |
| argStr = append(argStr, arg.String()) |
| } |
| return strings.Join(argStr, ", ") |
| } |
| |
| func buildImports(specs []importSpec) string { |
| var imports strings.Builder |
| imports.WriteString(` |
| import( |
| "errors" |
| "time" |
| |
| "github.com/moby/moby/v2/pkg/plugins" |
| `) |
| for _, i := range specs { |
| imports.WriteString("\t" + i.String() + "\n") |
| } |
| imports.WriteString(`) |
| `) |
| return imports.String() |
| } |
| |
| func marshalType(t string) string { |
| switch t { |
| case "error": |
| // convert error types to plain strings to ensure the values are encoded/decoded properly |
| return "string" |
| default: |
| return t |
| } |
| } |
| |
| func isErr(t string) bool { |
| switch t { |
| case "error": |
| return true |
| default: |
| return false |
| } |
| } |
| |
| // Need to use this helper due to issues with go-vet |
| func buildTag(s string) string { |
| return "+build " + s |
| } |
| |
| var templFuncs = template.FuncMap{ |
| "printArgs": printArgs, |
| "marshalType": marshalType, |
| "isErr": isErr, |
| "lower": strings.ToLower, |
| "title": title, |
| "tag": buildTag, |
| "imports": buildImports, |
| "goduration": goduration, |
| } |
| |
| // goduration formats a time.Duration as Go code (e.g., 2 * time.Minute) |
| func goduration(d time.Duration) string { |
| seconds := int64(d.Seconds()) |
| switch { |
| case d == 0: |
| return "0 * time.Nanosecond" |
| case seconds%(60*60) == 0 && seconds != 0: |
| return fmt.Sprintf("%d * time.Hour", seconds/3600) |
| case seconds%60 == 0 && seconds != 0: |
| return fmt.Sprintf("%d * time.Minute", seconds/60) |
| case seconds != 0: |
| return fmt.Sprintf("%d * time.Second", seconds) |
| default: |
| // fallback to nanoseconds for sub-second durations |
| return fmt.Sprintf("%d * time.Nanosecond", d.Nanoseconds()) |
| } |
| } |
| |
| func title(s string) string { |
| if strings.ToLower(s) == "id" { |
| return "ID" |
| } |
| return strings.Title(s) //nolint:staticcheck // SA1019: strings.Title is deprecated: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead. |
| } |
| |
| var generatedTempl = template.Must(template.New("rpc_cient").Funcs(templFuncs).Parse(` |
| // Code generated by pluginrpc-gen. DO NOT EDIT. |
| {{ range $k, $v := .BuildTags }} |
| // {{ tag $k }} {{ end }} |
| |
| package {{ .Name }} |
| |
| {{ imports .Imports }} |
| |
| const ( |
| longTimeout = {{ .LongTimeout | goduration }} |
| shortTimeout = {{ .ShortTimeout | goduration }} |
| ) |
| |
| type client interface{ |
| CallWithOptions(serviceMethod string, args interface{}, ret interface{}, opts ...func(*plugins.RequestOpts)) error |
| } |
| |
| type {{ .InterfaceType }}Proxy struct { |
| client |
| } |
| |
| {{ range .Functions }} |
| type {{ $.InterfaceType }}Proxy{{ .Name }}Request struct{ |
| {{- range .Args }} |
| {{ title .Name }} {{ .ArgType }} {{- end -}} |
| } |
| |
| type {{ $.InterfaceType }}Proxy{{ .Name }}Response struct{ |
| {{- range .Returns }} |
| {{ title .Name }} {{ marshalType .ArgType }} {{- end -}} |
| } |
| |
| {{- if .Doc }} |
| {{ .Doc }} |
| {{- end }} |
| func (pp *{{ $.InterfaceType }}Proxy) {{ .Name }}({{ printArgs .Args }}) ({{ printArgs .Returns }}) { |
| var( |
| req {{ $.InterfaceType }}Proxy{{ .Name }}Request |
| ret {{ $.InterfaceType }}Proxy{{ .Name }}Response |
| ) |
| {{ range .Args }} |
| req.{{ title .Name }} = {{ lower .Name }} {{ end }} |
| |
| if err = pp.CallWithOptions("{{ $.RPCName }}.{{ .Name }}", req, &ret, plugins.WithRequestTimeout({{ .TimeoutType }}Timeout)); err != nil { |
| return |
| } |
| {{ range $r := .Returns }} |
| {{ if isErr .ArgType }} |
| if ret.{{ title .Name }} != "" { |
| {{ lower .Name }} = errors.New(ret.{{ title .Name }}) |
| } {{ end }} |
| {{ if isErr .ArgType | not }} {{ lower .Name }} = ret.{{ title .Name }} {{ end }} {{ end }} |
| |
| return |
| } |
| {{ end }} |
| `)) |