github.com/alimy/mir/v4@v4.1.0/internal/generator/templates.go (about)

     1  // Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
     2  // Use of this source code is governed by Apache License 2.0 that
     3  // can be found in the LICENSE file.
     4  
     5  package generator
     6  
     7  import (
     8  	"bytes"
     9  	"embed"
    10  	"fmt"
    11  	"reflect"
    12  	"strings"
    13  	"text/template"
    14  
    15  	"github.com/alimy/mir/v4/core"
    16  	"github.com/alimy/mir/v4/internal/reflex"
    17  	"github.com/alimy/mir/v4/internal/utils"
    18  )
    19  
    20  //go:embed templates
    21  var content embed.FS
    22  
    23  // tmplInfos generator name map assets name
    24  var tmplInfos = map[string]string{
    25  	core.GeneratorGin:        "templates/gin_iface.tmpl",
    26  	core.GeneratorChi:        "templates/chi_iface.tmpl",
    27  	core.GeneratorMux:        "templates/mux_iface.tmpl",
    28  	core.GeneratorHertz:      "templates/hertz_iface.tmpl",
    29  	core.GeneratorEcho:       "templates/echo_iface.tmpl",
    30  	core.GeneratorIris:       "templates/iris_iface.tmpl",
    31  	core.GeneratorFiber:      "templates/fiber_iface.tmpl",
    32  	core.GeneratorMacaron:    "templates/macaron_iface.tmpl",
    33  	core.GeneratorHttpRouter: "templates/httprouter_iface.tmpl",
    34  }
    35  
    36  func templateFrom(name string) (*template.Template, error) {
    37  	tmplName, exist := tmplInfos[name]
    38  	if !exist {
    39  		return nil, fmt.Errorf("not exist templates for genererator:%s", name)
    40  	}
    41  	data, err := content.ReadFile(tmplName)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	t := template.New("mir").Funcs(template.FuncMap{
    46  		"declareImports": declareImports,
    47  		"declareTypes":   declareTypes,
    48  		"notEmptyStr":    notEmptyStr,
    49  		"joinPath":       joinPath,
    50  		"valideQuery":    valideQuery,
    51  		"inflateQuery":   inflateQuery,
    52  		"upperFirstName": upperFirstName,
    53  	})
    54  	if tmpl, err := t.Parse(string(data)); err == nil {
    55  		return tmpl, nil
    56  	} else {
    57  		return nil, err
    58  	}
    59  }
    60  
    61  func notEmptyStr(s string) bool {
    62  	return s != ""
    63  }
    64  
    65  func joinPath(group, subpath string) string {
    66  	if group == "" {
    67  		return subpath
    68  	}
    69  	b := &strings.Builder{}
    70  	if !strings.HasPrefix(group, "/") {
    71  		b.WriteByte('/')
    72  	}
    73  	b.WriteString(group)
    74  	if !strings.HasSuffix(group, "/") && !strings.HasPrefix(subpath, "/") {
    75  		b.WriteByte('/')
    76  	}
    77  	b.WriteString(subpath)
    78  	return b.String()
    79  }
    80  
    81  func valideQuery(qs []string) bool {
    82  	size := len(qs)
    83  	return size != 0 && size%2 == 0
    84  }
    85  
    86  func inflateQuery(qs []string) string {
    87  	var b strings.Builder
    88  	last := len(qs) - 1
    89  	b.Grow(last * 10)
    90  	for _, s := range qs {
    91  		b.WriteRune('"')
    92  		b.WriteString(s)
    93  		b.WriteString(`",`)
    94  	}
    95  	return strings.TrimRight(b.String(), ",")
    96  }
    97  
    98  func upperFirstName(name string) string {
    99  	return utils.UpperFirst(strings.ToLower(name))
   100  }
   101  
   102  func declareImports(imports map[string]string) string {
   103  	// write import declare to buffer
   104  	buf := &bytes.Buffer{}
   105  	for pkg, alias := range imports {
   106  		if alias != "" {
   107  			if _, err := buf.WriteString(alias + " "); err != nil {
   108  				break
   109  			}
   110  		}
   111  		if _, err := buf.WriteString(`"` + pkg + "\"\n"); err != nil {
   112  			break
   113  		}
   114  	}
   115  	return buf.String()
   116  }
   117  
   118  func declareTypes(inOuts []reflect.Type, pkgPath string, imports map[string]string) string {
   119  	if len(inOuts) == 0 {
   120  		return ""
   121  	}
   122  	var err error
   123  
   124  	// write types that in inOuts to buffer
   125  	indent := "    "
   126  	buf := &bytes.Buffer{}
   127  	for _, t := range inOuts {
   128  		err := reflex.WriteStruct(buf, t, pkgPath, imports, indent)
   129  		if err != nil {
   130  			break
   131  		}
   132  		if _, err = buf.WriteString("\n"); err != nil {
   133  			break
   134  		}
   135  	}
   136  	if err != nil {
   137  		core.Logus("write declare types error: %s", err)
   138  		return ""
   139  	}
   140  	return buf.String()
   141  }