template.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package main
  2. import (
  3. "strings"
  4. "text/template"
  5. )
  6. func printArgs(args []arg) string {
  7. var argStr []string
  8. for _, arg := range args {
  9. argStr = append(argStr, arg.String())
  10. }
  11. return strings.Join(argStr, ", ")
  12. }
  13. func buildImports(specs []importSpec) string {
  14. if len(specs) == 0 {
  15. return `import "errors"`
  16. }
  17. imports := "import(\n"
  18. imports += "\t\"errors\"\n"
  19. for _, i := range specs {
  20. imports += "\t" + i.String() + "\n"
  21. }
  22. imports += ")"
  23. return imports
  24. }
  25. func marshalType(t string) string {
  26. switch t {
  27. case "error":
  28. // convert error types to plain strings to ensure the values are encoded/decoded properly
  29. return "string"
  30. default:
  31. return t
  32. }
  33. }
  34. func isErr(t string) bool {
  35. switch t {
  36. case "error":
  37. return true
  38. default:
  39. return false
  40. }
  41. }
  42. // Need to use this helper due to issues with go-vet
  43. func buildTag(s string) string {
  44. return "+build " + s
  45. }
  46. var templFuncs = template.FuncMap{
  47. "printArgs": printArgs,
  48. "marshalType": marshalType,
  49. "isErr": isErr,
  50. "lower": strings.ToLower,
  51. "title": title,
  52. "tag": buildTag,
  53. "imports": buildImports,
  54. }
  55. func title(s string) string {
  56. if strings.ToLower(s) == "id" {
  57. return "ID"
  58. }
  59. return strings.Title(s)
  60. }
  61. var generatedTempl = template.Must(template.New("rpc_cient").Funcs(templFuncs).Parse(`
  62. // generated code - DO NOT EDIT
  63. {{ range $k, $v := .BuildTags }}
  64. // {{ tag $k }} {{ end }}
  65. package {{ .Name }}
  66. {{ imports .Imports }}
  67. type client interface{
  68. Call(string, interface{}, interface{}) error
  69. }
  70. type {{ .InterfaceType }}Proxy struct {
  71. client
  72. }
  73. {{ range .Functions }}
  74. type {{ $.InterfaceType }}Proxy{{ .Name }}Request struct{
  75. {{ range .Args }}
  76. {{ title .Name }} {{ .ArgType }} {{ end }}
  77. }
  78. type {{ $.InterfaceType }}Proxy{{ .Name }}Response struct{
  79. {{ range .Returns }}
  80. {{ title .Name }} {{ marshalType .ArgType }} {{ end }}
  81. }
  82. func (pp *{{ $.InterfaceType }}Proxy) {{ .Name }}({{ printArgs .Args }}) ({{ printArgs .Returns }}) {
  83. var(
  84. req {{ $.InterfaceType }}Proxy{{ .Name }}Request
  85. ret {{ $.InterfaceType }}Proxy{{ .Name }}Response
  86. )
  87. {{ range .Args }}
  88. req.{{ title .Name }} = {{ lower .Name }} {{ end }}
  89. if err = pp.Call("{{ $.RPCName }}.{{ .Name }}", req, &ret); err != nil {
  90. return
  91. }
  92. {{ range $r := .Returns }}
  93. {{ if isErr .ArgType }}
  94. if ret.{{ title .Name }} != "" {
  95. {{ lower .Name }} = errors.New(ret.{{ title .Name }})
  96. } {{ end }}
  97. {{ if isErr .ArgType | not }} {{ lower .Name }} = ret.{{ title .Name }} {{ end }} {{ end }}
  98. return
  99. }
  100. {{ end }}
  101. `))