dotcloud/docker

View on GitHub
pkg/plugins/pluginrpc-gen/template.go

Summary

Maintainability
A
0 mins
Test Coverage
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 }}
`))