awalterschulze / goderive
- суббота, 26 августа 2017 г. в 03:14:21
Next generation code generator for go
goderive
derives mundane golang functions that you do not want to maintain and keeps them up to date.
It does thing by parsing your go code for functions which are not implemented and then generates these functions for you by deriving their implementations from the parameter types.
Recursive Functions:
deriveEqual(T, T) bool
deriveCompare(T, T) int
deriveDeepCopy(dst *T, src *T)
deriveDeepCopy(dst []T, src []T)
deriveDeepCopy(dst map[A]B, src map[A]B)
deriveGoString(T) string
Set Functions:
deriveKeys(map[K]V) []K
deriveSort([]T) []T
deriveUnique([]T) []T
deriveSet([]T) map[T]struct{}
deriveMin(list []T, default T) (min T)
deriveMin(T, T) T
deriveMax(list []T, default T) (max T)
deriveMax(T, T) T
deriveContains([]T, T) bool
deriveIntersect(a, b []T) []T
deriveIntersect(a, b map[T]struct{}) map[T]struct{}
deriveUnion(a, b []T) []T
deriveUnion(a, b map[T]struct{}) map[T]struct{}
Functional Functions:
deriveFmap(func(A) B, []A) []B
deriveFmap(func(rune) B, string) []B
deriveFmap(func(A) B, func() (A, error)) (B, error)
deriveFmap(func(A) (B, error), func() (A, error)) (func() (B, error), error)
deriveFmap(func(A), func() (A, error)) error
deriveFmap(func(A) (B, c, d, ...), func() (A, error)) (func() (B, c, d, ...), error)
deriveJoin([][]T) []T
deriveJoin([]string) string
deriveJoin(func() (T, error), error) func() (T, error)
deriveJoin(func() (T, ..., error), error) func() (T, ..., error)
deriveFilter(pred func(T) bool, []T) []T
deriveAll(pred func(T) bool, []T) bool
deriveAny(pred func(T) bool, []T) bool
deriveTakeWhile(pred func(T) bool, []T) []T
deriveFlip(f func(A, B, ...) T) func(B, A, ...) T
deriveCurry(f func(A, B, ...) T) func(A) func(B, ...) T
deriveUncurry(f func(A) func(B, ...) T) func(A, B, ...) T
deriveTuple(A, B, ...) func() (A, B, ...)
deriveCompose(func() (A, error), func(A) (B, error)) (B, error)
deriveCompose(func(A) (B, error), func(B) (C, error)) func(A) (C, error)
deriveCompose(func(A...) (B..., error), func(B...) (C..., error)) func(A...) (C..., error)
Concurrency Functions:
deriveFmap(func(A) B, <-chan A) <-chan B
deriveJoin(<-chan <-chan T) <-chan T
derivePipeline(func(A) <-chan B, func(B) <-chan C) func(A) <-chan C
deriveDo(func() (A, error), func (B, error)) (A, B, error)
When goderive walks over your code it is looking for a function that:
Functions which have been previously derived will be regenerated to keep them up to date with the latest modifications to your types. This keeps these functions, which are truly mundane to write, maintainable.
For example when someone in your team adds a new field to a struct and forgets to update the CopyTo method. This problem is solved by goderive, by generating generated functions given the new types.
Function prefixes are by default deriveCamelCaseFunctionName
, for example deriveEqual
.
These are customizable using command line flags.
Let goderive
edit your function names in your source code, by enabling autoname
and dedup
using the command line flags.
These flags respectively makes sure than your functions have unique names and that you don't generate multiple functions that do the same thing.
In the following code the deriveEqual
function will be spotted as a function that was not implemented (or was previously derived) and has a prefix deriveEqual
.
package main
type MyStruct struct {
Int64 int64
StringPtr *string
}
func (this *MyStruct) Equal(that *MyStruct) bool {
return deriveEqual(this, that)
}
goderive will then generate the following code in a derived.gen.go
file in the same package:
func deriveEqual(this, that *MyStruct) bool {
return (this == nil && that == nil) ||
this != nil && that != nil &&
this.Int64 == that.Int64 &&
((this.StringPtr == nil && that.StringPtr == nil) ||
(this.StringPtr != nil && that.StringPtr != nil && *(this.StringPtr) == *(that.StringPtr)))
}
Recursive Examples:
Set Examples:
Concurrency Examples:
goderive can be run from the command line:
goderive ./...
, using the same path semantics as the go tool.
You can also run goderive using go generate
And you can customize specific function prefixes
Or you can customize all function prefixes
You can let goderive rename your functions using the -autoname
and -dedup
flags.
If these flags are not used, goderive will not touch your code and rather return an error.
The derive package allows you to create your own code generator plugins, see all the current plugins for examples.
You can also create your own vanity binary. Including your own generators and/or customization of function prefixes, etc. This should be easy to figure out by looking at main.go
These projects use goderive: