| package main | |
| import ( | |
| "strings" | |
| "text/template" | |
| ) | |
| func printArgs(args []arg) string { | |
| var argStr []string | |
| for _, arg := range args { | |
| argStr = append(argStr, arg.String()) | |
| } | |
| return strings.Join(argStr, ", ") | |
| } | |
| func buildImports(specs []importSpec) string { | |
| if len(specs) == 0 { | |
| return `import "errors"` | |
| } | |
| imports := "import(\n" | |
| imports += "\t\"errors\"\n" | |
| for _, i := range specs { | |
| imports += "\t" + i.String() + "\n" | |
| } | |
| imports += ")" | |
| return imports | |
| } | |
| 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, | |
| } | |
| 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(` | |
| // generated code - DO NOT EDIT | |
| {{ range $k, $v := .BuildTags }} | |
| // {{ tag $k }} {{ end }} | |
| package {{ .Name }} | |
| {{ imports .Imports }} | |
| type client interface{ | |
| Call(string, interface{}, interface{}) 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 }} | |
| } | |
| 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.Call("{{ $.RPCName }}.{{ .Name }}", req, &ret); 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 }} | |
| `)) |