Skip to content

Commit

Permalink
optimize generator and parser init logic
Browse files Browse the repository at this point in the history
  • Loading branch information
alimy committed Mar 6, 2020
1 parent d223b0f commit 81f585c
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 161 deletions.
43 changes: 15 additions & 28 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

package core

import (
"log"
"os"
"path/filepath"
// options key list
const (
OptSinkPath = "sinkPath"
OptDefaultTag = "defaultTag"
)

var (
Expand All @@ -27,44 +27,29 @@ var (
ParserStructTag = "structTag"
)

// Opts use for generator or parser init
type InitOpts = map[string]string

// Options generator options
type Options struct {
GeneratorName string
ParserName string
OutPath string
GeneratorOpts InitOpts
ParserOpts InitOpts
}

// Parser parse entries
type Parser interface {
Name() string
Init(opts InitOpts) error
Parse(entries []interface{}) (Descriptors, error)
}

// Generator generate interface code for engine
type Generator interface {
Name() string
Generate(Descriptors, *Options) error
}

// SinkPath return output path
func (p *Options) SinkPath() string {
path, err := filepath.EvalSymlinks(p.OutPath)
if err != nil {
if os.IsNotExist(err) {
if !filepath.IsAbs(p.OutPath) {
cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
path = filepath.Join(cwd, p.OutPath)
} else {
path = p.OutPath
}
} else {
log.Fatal(err)
}
}
return path
Init(opts InitOpts) error
Generate(Descriptors) error
}

// RegisterGenerators register generators
Expand All @@ -90,7 +75,9 @@ func DefaultOptions() *Options {
return &Options{
GeneratorName: GeneratorGin,
ParserName: ParserStructTag,
OutPath: "./gen",
GeneratorOpts: InitOpts{
OptSinkPath: "./gen",
},
}
}

Expand Down
13 changes: 9 additions & 4 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

// Generate generate interface code
func Generate(entries []interface{}, opts *core.Options) error {
func Generate(entries []interface{}, opts *core.Options) (err error) {
if opts == nil {
return errors.New("options is nil")
}
Expand All @@ -25,15 +25,20 @@ func Generate(entries []interface{}, opts *core.Options) error {
if p == nil {
return errors.New("parser is nil")
}
if err = p.Init(opts.ParserOpts); err != nil {
return
}

g := core.GeneratorByName(opts.GeneratorName)
if g == nil {
return fmt.Errorf("unknow generators that name %s", opts.GeneratorName)
}
if err = g.Init(opts.GeneratorOpts); err != nil {
return
}

mirTags, err := p.Parse(entries)
if err != nil {
return g.Generate(mirTags, opts)
if mirTags, err := p.Parse(entries); err == nil {
return g.Generate(mirTags)
}
return err
}
66 changes: 58 additions & 8 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package generator

import (
"errors"
"fmt"
"os"
"path"
Expand All @@ -16,11 +17,43 @@ import (
"github.com/alimy/mir/v2/core"
)

var (
errNotExistSinkPath = errors.New("not exist output path")
)

func init() {
core.RegisterGenerators(generatorGin{},
generatorChi{},
generatorMux{},
generatorHttpRouter{})
core.RegisterGenerators(
mirGenerator{name: core.GeneratorGin},
mirGenerator{name: core.GeneratorChi},
mirGenerator{name: core.GeneratorMux},
mirGenerator{name: core.GeneratorHttpRouter},
)
}

type mirGenerator struct {
sinkPath string
name string
}

// Name name of generator
func (g mirGenerator) Name() string {
return g.name
}

// Init init generator
func (g mirGenerator) Init(opts core.InitOpts) (err error) {
if len(opts) != 0 {
if sp, exist := opts[core.OptSinkPath]; exist {
g.sinkPath, err = evalSinkPath(sp)
return
}
}
return errNotExistSinkPath
}

// Generate generate interface code
func (g mirGenerator) Generate(ds core.Descriptors) error {
return generate(g.name, g.sinkPath, ds)
}

func notEmptyStr(s string) bool {
Expand Down Expand Up @@ -48,23 +81,23 @@ func inflateQuery(qs []string) string {
return strings.TrimRight(b.String(), ",")
}

func generate(ds core.Descriptors, opts *core.Options) error {
func generate(generatorName string, sinkPath string, ds core.Descriptors) error {
var (
err error
dirPath, filePath string
)

apiPath := filepath.Join(opts.SinkPath(), "api")
apiPath := filepath.Join(sinkPath, "api")
tmpl := template.New("mir").Funcs(template.FuncMap{
"notEmptyStr": notEmptyStr,
"notHttpAny": notHttpAny,
"join": path.Join,
"valideQuery": valideQuery,
"inflateQuery": inflateQuery,
})
assetName, exist := tmplFiles[opts.GeneratorName]
assetName, exist := tmplFiles[generatorName]
if !exist {
return fmt.Errorf("not exist templates for genererator:%s", opts.GeneratorName)
return fmt.Errorf("not exist templates for genererator:%s", generatorName)
}
if tmpl, err = tmpl.Parse(MustAssetString(assetName)); err != nil {
return err
Expand Down Expand Up @@ -94,3 +127,20 @@ FuckErr:

return err
}

func evalSinkPath(path string) (string, error) {
sp, err := filepath.EvalSymlinks(path)
if err != nil {
if os.IsNotExist(err) {
if !filepath.IsAbs(path) {
if cwd, err := os.Getwd(); err == nil {
sp = filepath.Join(cwd, path)
}
} else {
sp = path
err = nil
}
}
}
return sp, err
}
25 changes: 0 additions & 25 deletions internal/generator/generator_chi.go

This file was deleted.

22 changes: 0 additions & 22 deletions internal/generator/generator_gin.go

This file was deleted.

25 changes: 0 additions & 25 deletions internal/generator/generator_httprouter.go

This file was deleted.

25 changes: 0 additions & 25 deletions internal/generator/generator_mux.go

This file was deleted.

4 changes: 2 additions & 2 deletions internal/parser/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ type tagInfo struct {
}

// tagInfoFrom build tagInfo from field
func tagInfoFrom(field reflect.StructField) (*tagInfo, error) {
func (p mirParser) tagInfoFrom(field reflect.StructField) (*tagInfo, error) {
info := &tagInfo{}

// lookup mir tag info from struct field
tag, exist := field.Tag.Lookup(defaultTag)
tag, exist := field.Tag.Lookup(p.tagName)
if !exist {
return nil, errNotExist
}
Expand Down
37 changes: 19 additions & 18 deletions internal/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,34 @@ import (
)

func init() {
core.RegisterParsers(parserStructTag{})
core.RegisterParsers(mirParser{tagName: defaultTag})
}

// parserStructTag parse for struct tag
type parserStructTag struct{}
// mirParser parse for struct tag
type mirParser struct {
tagName string
}

// Name name of parser
func (parserStructTag) Name() string {
func (p mirParser) Name() string {
return core.ParserStructTag
}

// Parse parse interface define object entries
func (parserStructTag) Parse(entries []interface{}) (core.Descriptors, error) {
if len(entries) == 0 {
return nil, errors.New("entries is empty")
// Init init parser
func (p mirParser) Init(opts core.InitOpts) error {
if len(opts) != 0 {
p.tagName = opts[core.OptDefaultTag]
}
return reflex(entries)
}

// SetDefaultTag set default tag name
func SetDefaultTag(tag string) {
if len(tag) > 0 {
defaultTag = tag
if p.tagName == "" {
p.tagName = defaultTag
}
return nil
}

// DefaultTag return default tag name
func DefaultTag() string {
return defaultTag
// Parse parse interface define object entries
func (p mirParser) Parse(entries []interface{}) (core.Descriptors, error) {
if len(entries) == 0 {
return nil, errors.New("entries is empty")
}
return p.reflex(entries)
}
Loading

0 comments on commit 81f585c

Please sign in to comment.