genappevent

package
v0.0.0-...-c34678f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2019 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var GoAdapterPubsubberBaseTmpl = TemplateRenderer{
	Tmpl: template.Must(template.New("GoAdapterPubsubberBaseTmpl").Funcs(map[string]interface{}{
		"FmtImports":   FmtImports,
		"ToUpperCamel": ToUpperCamel,
		"ToLowerCamel": ToLowerCamel,
		"ToApplicationType": func(paranName, paramType string) string {
			typ := paramType
			typ = strings.TrimPrefix(typ, "[]")
			typ = strings.TrimPrefix(typ, "*")
			switch typ {
			case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16",
				"uint32", "uint64", "uintptr",
				"byte", "rune",
				"float32", "float64",
				"complex64",
				"string",
				"time.Time":
				return fmt.Sprintf("event.%s()", ToUpperCamel(paranName))
			default:
				return fmt.Sprintf("%s(event.%s())", paramType, ToUpperCamel(paranName))
			}
		},
		"ToAppeventType": func(paranName, paramType string) string {
			typ := paramType
			typ = strings.TrimPrefix(typ, "[]")
			typ = strings.TrimPrefix(typ, "*")
			switch typ {
			case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16",
				"uint32", "uint64", "uintptr",
				"byte", "rune",
				"float32", "float64",
				"complex64",
				"string",
				"time.Time":
				return fmt.Sprintf("event.%s()", ToUpperCamel(paranName))
			default:
				return fmt.Sprintf("string(event.%s())", ToUpperCamel(paranName))
			}
		},
	}).Parse(`
// Code generated ; DO NOT EDIT

package appevent

{{ FmtImports .ImportPackages }}

type EventPublisher struct {
	{{- range .Events }}
	{{ .Name }}EventPublisher
	{{- end }}
}

func NewEventPublisher(
	{{- range .Events }}
	{{ ToLowerCamel .Name }}EventPublisher {{ .Name }}EventPublisher,
	{{- end }}
) EventPublisher {
	return EventPublisher{
		{{- range .Events }}
		{{ .Name }}EventPublisher: {{ ToLowerCamel .Name }}EventPublisher,
		{{- end }}
	}
}

{{ range .Events }}

	type {{ .Name }}EventPublisher struct {
		publisher appevent.{{ .Name }}EventPublisher
		bufSize int
	}

	func New{{ .Name }}EventPublisher(
		publisher appevent.{{ .Name }}EventPublisher,
		bufSize int,
	) {{ .Name }}EventPublisher {
		return {{ .Name }}EventPublisher{
			publisher: publisher,
			bufSize: bufSize,
		}
	}

	func (p {{ .Name }}EventPublisher) Publish{{ .Name }}Event(ctx context.Context, event application.{{ .Name }}Event) <-chan domain.Error {
		c := make(chan domain.Error, p.bufSize)
		go func() {
			defer close(c)
			errSrc := p.publisher.Publish{{ .Name }}Event(
				ctx,
				appevent.New{{ .Name }}Event(
					event.OccurredOn(),
					{{- range .Params }}
					{{ ToAppeventType .Name .Type }},
					{{- end }}
				),
			)
			for err := range errSrc {
				c <- domain.ErrorUnknown(err)
			}
		}()
		return c
	}

	type {{ .Name }}EventSubscriber struct {
		subscriber appevent.{{ .Name }}EventSubscriber
		bufSize int
	}

	func New{{ .Name }}EventSubscriber(
		subscriber appevent.{{ .Name }}EventSubscriber,
		bufSize int,
	) {{ .Name }}EventSubscriber {
		return {{ .Name }}EventSubscriber{
			subscriber: subscriber,
			bufSize: bufSize,
		}
	}

	func (p {{ .Name }}EventSubscriber) Subscribe{{ .Name }}Event(ctx context.Context) (<-chan application.{{ .Name }}Event, domain.Error) {
		src, err := p.subscriber.Subscribe{{ .Name }}Event(ctx)
		if err != nil {
			return nil, domain.ErrorUnknown(err)
		}
		c := make(chan application.{{ .Name }}Event, p.bufSize)
		go func() {
			defer close(c)
			for event := range src {
				c <- application.New{{ .Name }}Event(
					event.OccurredOn(),
					{{- range .Params }}
					{{ ToApplicationType .Name .Type }},
					{{- end }}
				)
			}
		}()
		return c, nil
	}
{{- end }}
`)),
	ResolveImportPackages: func(paramType string, recommendedImportPackages ...string) []string {
		results := make([]string, 0, 4)
		results = append(results, "context")

		for _, pkgPath := range recommendedImportPackages {
			if "appevent" == path.Base(pkgPath) || "application" == path.Base(pkgPath) {
				results = append(results, pkgPath)
			}
		}

		if !strings.Contains(paramType, ".") {
			return results
		}
		for _, s := range strings.FieldsFunc(paramType, func(c rune) bool {
			return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.'
		}) {
			ss := strings.SplitN(s, ".", 2)
			if len(ss) != 2 {
				continue
			}
			for _, pkgPath := range recommendedImportPackages {
				if ss[0] == path.Base(pkgPath) {
					results = append(results, pkgPath)
					break
				}
			}
		}
		return results
	},
}
View Source
var GoApplicationTmpl = TemplateRenderer{
	Tmpl: template.Must(template.New("GoApplicationTmpl").Funcs(map[string]interface{}{
		"FmtImports":   FmtImports,
		"ToUpperCamel": ToUpperCamel,
	}).Parse(`
// Code generated ; DO NOT EDIT

package {{ .PackageName }}

{{ FmtImports .ImportPackages }}

{{ range .Events }}
	type {{ .Name }}Event struct {
		occurredOn time.Time
		{{- range .Params }}
		{{ .Name }} {{ .Type }}
		{{- end }}
	}

	func New{{ .Name }}Event(
			occurredOn time.Time,
		{{- range .Params }}
		{{ .Name }} {{ .Type }},
		{{- end }}
	) {{ .Name }}Event {
		return {{ .Name }}Event{
			occurredOn: occurredOn,
			{{- range .Params }}
			{{ .Name }}: {{ .Name }},
			{{- end }}
		}
	}

	func (e {{ .Name }}Event) EventName() string {
		return "{{ .Name }}"
	}

	func (e {{ .Name }}Event) OccurredOn() time.Time {
		return e.occurredOn
	}

	{{ $EventName := .Name }}
	{{- range .Params }}
	func (e {{ $EventName }}Event) {{ ToUpperCamel .Name }}() {{ .Type }} {
		return e.{{ .Name }}
	}
	{{- end }}

	type {{ .Name }}EventPublisher interface {
		Publish{{ .Name }}Event(context.Context, {{ .Name }}Event) <-chan domain.Error
	}

	type {{ .Name }}EventSubscriber interface {
		Subscribe{{ .Name }}Event(context.Context) (<-chan {{ .Name }}Event, domain.Error)
	}
{{- end }}
`)),
	ResolveImportPackages: func(paramType string, recommendedImportPackages ...string) []string {
		results := make([]string, 0, 4)
		results = append(results, "context", "time")

		if !strings.Contains(paramType, ".") {
			return results
		}
		for _, s := range strings.FieldsFunc(paramType, func(c rune) bool {
			return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.'
		}) {
			ss := strings.SplitN(s, ".", 2)
			if len(ss) != 2 {
				continue
			}
			for _, pkgPath := range recommendedImportPackages {
				if ss[0] == path.Base(pkgPath) {
					results = append(results, pkgPath)
					break
				}
			}
		}
		return results
	},
}
View Source
var GoExternalClientTmpl = TemplateRenderer{
	Tmpl: template.Must(template.New("GoExternalClientTmpl").Funcs(map[string]interface{}{
		"FmtImports":   FmtImports,
		"ToUpperCamel": ToUpperCamel,
		"TypeConverter": func(paramType string) string {
			typ := paramType
			typ = strings.TrimPrefix(typ, "[]")
			typ = strings.TrimPrefix(typ, "*")
			switch typ {
			case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16",
				"uint32", "uint64", "uintptr",
				"byte", "rune",
				"float32", "float64",
				"complex64",
				"string",
				"time.Time":
				return paramType
			default:
				return strings.Replace(paramType, typ, "string", -1)
			}
		},
	}).Parse(`
// Code generated ; DO NOT EDIT

package appevent

{{ FmtImports .ImportPackages }}

{{ range .Events }}
	type {{ .Name }}Event struct {
		occurredOn time.Time
		{{- range .Params }}
		{{ .Name }} {{ TypeConverter .Type }}
		{{- end }}
	}

	func New{{ .Name }}Event(
			occurredOn time.Time,
		{{- range .Params }}
		{{ .Name }} {{ TypeConverter .Type }},
		{{- end }}
	) {{ .Name }}Event {
		return {{ .Name }}Event{
			occurredOn: occurredOn,
			{{- range .Params }}
			{{ .Name }}: {{ .Name }},
			{{- end }}
		}
	}

	func (e {{ .Name }}Event) EventName() string {
		return "{{ .Name }}"
	}

	func (e {{ .Name }}Event) OccurredOn() time.Time {
		return e.occurredOn
	}

	{{ $EventName := .Name }}
	{{- range .Params }}
	func (e {{ $EventName }}Event) {{ ToUpperCamel .Name }}() {{ TypeConverter .Type }} {
		return e.{{ .Name }}
	}
	{{- end }}

	type {{ .Name }}EventPublisher interface {
		Publish{{ .Name }}Event(context.Context, {{ .Name }}Event) <-chan error
	}

	type {{ .Name }}EventSubscriber interface {
		Subscribe{{ .Name }}Event(context.Context) (<-chan {{ .Name }}Event, error)
	}

	type {{ .Name }}EventPublishers struct {
		publishers []{{ .Name }}EventPublisher
		bufSize int
	}

	func New{{ .Name }}EventPublishers(
		publishers []{{ .Name }}EventPublisher,
		bufSize int,
	) {{ .Name }}EventPublishers {
		return {{ .Name }}EventPublishers{
			publishers: publishers,
			bufSize: bufSize,
		}
	}

	func (ps {{ .Name }}EventPublishers) Publish{{ .Name }}Event(ctx context.Context, event {{ .Name }}Event) <-chan error {
		wg := new(sync.WaitGroup)
		c := make(chan error, ps.bufSize)
		go func() {
			defer close(c)
			wg.Wait()
		}()
		for i := range ps.publishers {
			wg.Add(1)
			go func() {
				wg.Done()
				for err := range ps.publishers[i].Publish{{ .Name }}Event(ctx, event) {
					c <- err
				}
			}()
		}
		return c
	}

{{- end }}
`)),
	ResolveImportPackages: func(paramType string, recommendedImportPackages ...string) []string {
		return []string{"context", "sync", "time"}
	},
}

Functions

func FmtImports

func FmtImports(pkgs []string) string

func Run

func Run(targetDir string, renderers ...func(TmplParam) error) error
Example (GenForGoAdapterPubsubberBaseTmpl)
package main

import (
	"log"
	"os"

	"github.com/hori-ryota/go-genappevent/genappevent"
)

func main() {
	targetDir := "../_example/application"
	if err := genappevent.Run(
		targetDir,
		genappevent.GoAdapterPubsubberBaseTmpl.RendererFunc(
			os.Stdout,
			"github.com/hori-ryota/go-genappevent/_example/application",
			"github.com/hori-ryota/go-genappevent/_example/domain",
			"github.com/hori-ryota/go-genappevent/_example/external/appevent",
		),
	); err != nil {
		log.Fatal(err)
	}
}
Output:

// Code generated ; DO NOT EDIT

package appevent

import (
	"context"

	"github.com/hori-ryota/go-genappevent/_example/application"
	"github.com/hori-ryota/go-genappevent/_example/domain"
	"github.com/hori-ryota/go-genappevent/_example/external/appevent"
)

type EventPublisher struct {
	ShopOpenedEventPublisher
}

func NewEventPublisher(
	shopOpenedEventPublisher ShopOpenedEventPublisher,
) EventPublisher {
	return EventPublisher{
		ShopOpenedEventPublisher: shopOpenedEventPublisher,
	}
}

type ShopOpenedEventPublisher struct {
	publisher appevent.ShopOpenedEventPublisher
	bufSize   int
}

func NewShopOpenedEventPublisher(
	publisher appevent.ShopOpenedEventPublisher,
	bufSize int,
) ShopOpenedEventPublisher {
	return ShopOpenedEventPublisher{
		publisher: publisher,
		bufSize:   bufSize,
	}
}

func (p ShopOpenedEventPublisher) PublishShopOpenedEvent(ctx context.Context, event application.ShopOpenedEvent) <-chan domain.Error {
	c := make(chan domain.Error, p.bufSize)
	go func() {
		defer close(c)
		errSrc := p.publisher.PublishShopOpenedEvent(
			ctx,
			appevent.NewShopOpenedEvent(
				event.OccurredOn(),
				string(event.ShopID()),
				event.OperatorID(),
				event.OperatorType(),
			),
		)
		for err := range errSrc {
			c <- domain.ErrorUnknown(err)
		}
	}()
	return c
}

type ShopOpenedEventSubscriber struct {
	subscriber appevent.ShopOpenedEventSubscriber
	bufSize    int
}

func NewShopOpenedEventSubscriber(
	subscriber appevent.ShopOpenedEventSubscriber,
	bufSize int,
) ShopOpenedEventSubscriber {
	return ShopOpenedEventSubscriber{
		subscriber: subscriber,
		bufSize:    bufSize,
	}
}

func (p ShopOpenedEventSubscriber) SubscribeShopOpenedEvent(ctx context.Context) (<-chan application.ShopOpenedEvent, domain.Error) {
	src, err := p.subscriber.SubscribeShopOpenedEvent(ctx)
	if err != nil {
		return nil, domain.ErrorUnknown(err)
	}
	c := make(chan application.ShopOpenedEvent, p.bufSize)
	go func() {
		defer close(c)
		for event := range src {
			c <- application.NewShopOpenedEvent(
				event.OccurredOn(),
				domain.ShopID(event.ShopID()),
				event.OperatorID(),
				event.OperatorType(),
			)
		}
	}()
	return c, nil
}
Example (GenForGoApplicationTmpl)
package main

import (
	"log"
	"os"

	"github.com/hori-ryota/go-genappevent/genappevent"
)

func main() {
	targetDir := "../_example/application"
	if err := genappevent.Run(
		targetDir,
		genappevent.GoApplicationTmpl.RendererFunc(
			os.Stdout,
			"github.com/hori-ryota/go-genappevent/_example/domain",
		),
	); err != nil {
		log.Fatal(err)
	}
}
Output:

// Code generated ; DO NOT EDIT

package application

import (
	"context"
	"time"

	"github.com/hori-ryota/go-genappevent/_example/domain"
)

type ShopOpenedEvent struct {
	occurredOn   time.Time
	shopID       domain.ShopID
	operatorID   string
	operatorType string
}

func NewShopOpenedEvent(
	occurredOn time.Time,
	shopID domain.ShopID,
	operatorID string,
	operatorType string,
) ShopOpenedEvent {
	return ShopOpenedEvent{
		occurredOn:   occurredOn,
		shopID:       shopID,
		operatorID:   operatorID,
		operatorType: operatorType,
	}
}

func (e ShopOpenedEvent) EventName() string {
	return "ShopOpened"
}

func (e ShopOpenedEvent) OccurredOn() time.Time {
	return e.occurredOn
}

func (e ShopOpenedEvent) ShopID() domain.ShopID {
	return e.shopID
}
func (e ShopOpenedEvent) OperatorID() string {
	return e.operatorID
}
func (e ShopOpenedEvent) OperatorType() string {
	return e.operatorType
}

type ShopOpenedEventPublisher interface {
	PublishShopOpenedEvent(context.Context, ShopOpenedEvent) <-chan domain.Error
}

type ShopOpenedEventSubscriber interface {
	SubscribeShopOpenedEvent(context.Context) (<-chan ShopOpenedEvent, domain.Error)
}
Example (GenForGoExternalClientTmpl)
package main

import (
	"log"
	"os"

	"github.com/hori-ryota/go-genappevent/genappevent"
)

func main() {
	targetDir := "../_example/application"
	if err := genappevent.Run(
		targetDir,
		genappevent.GoExternalClientTmpl.RendererFunc(
			os.Stdout,
			"github.com/hori-ryota/go-genappevent/_example/application",
			"github.com/hori-ryota/go-genappevent/_example/domain",
		),
	); err != nil {
		log.Fatal(err)
	}
}
Output:

// Code generated ; DO NOT EDIT

package appevent

import (
	"context"
	"sync"
	"time"
)

type ShopOpenedEvent struct {
	occurredOn   time.Time
	shopID       string
	operatorID   string
	operatorType string
}

func NewShopOpenedEvent(
	occurredOn time.Time,
	shopID string,
	operatorID string,
	operatorType string,
) ShopOpenedEvent {
	return ShopOpenedEvent{
		occurredOn:   occurredOn,
		shopID:       shopID,
		operatorID:   operatorID,
		operatorType: operatorType,
	}
}

func (e ShopOpenedEvent) EventName() string {
	return "ShopOpened"
}

func (e ShopOpenedEvent) OccurredOn() time.Time {
	return e.occurredOn
}

func (e ShopOpenedEvent) ShopID() string {
	return e.shopID
}
func (e ShopOpenedEvent) OperatorID() string {
	return e.operatorID
}
func (e ShopOpenedEvent) OperatorType() string {
	return e.operatorType
}

type ShopOpenedEventPublisher interface {
	PublishShopOpenedEvent(context.Context, ShopOpenedEvent) <-chan error
}

type ShopOpenedEventSubscriber interface {
	SubscribeShopOpenedEvent(context.Context) (<-chan ShopOpenedEvent, error)
}

type ShopOpenedEventPublishers struct {
	publishers []ShopOpenedEventPublisher
	bufSize    int
}

func NewShopOpenedEventPublishers(
	publishers []ShopOpenedEventPublisher,
	bufSize int,
) ShopOpenedEventPublishers {
	return ShopOpenedEventPublishers{
		publishers: publishers,
		bufSize:    bufSize,
	}
}

func (ps ShopOpenedEventPublishers) PublishShopOpenedEvent(ctx context.Context, event ShopOpenedEvent) <-chan error {
	wg := new(sync.WaitGroup)
	c := make(chan error, ps.bufSize)
	go func() {
		defer close(c)
		wg.Wait()
	}()
	for i := range ps.publishers {
		wg.Add(1)
		go func() {
			wg.Done()
			for err := range ps.publishers[i].PublishShopOpenedEvent(ctx, event) {
				c <- err
			}
		}()
	}
	return c
}

func ToLowerCamel

func ToLowerCamel(s string) string

func ToUpperCamel

func ToUpperCamel(s string) string

Types

type EventInfo

type EventInfo struct {
	Name   string
	Params []ParamInfo
}

type ParamInfo

type ParamInfo struct {
	Name string
	Type string
}

type TemplateRenderer

type TemplateRenderer struct {
	Tmpl                  *template.Template
	ResolveImportPackages func(paramType string, recommendedImportPackages ...string) []string
}

func (TemplateRenderer) RendererFunc

func (r TemplateRenderer) RendererFunc(w io.Writer, recommendedImportPackages ...string) func(param TmplParam) error

type TmplParam

type TmplParam struct {
	PackageName    string
	Events         []EventInfo
	ImportPackages []string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL