Skip to content

Instantly share code, notes, and snippets.

@sdboyer
Last active November 1, 2022 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sdboyer/b482d1489311c6fd97c9281be65b1752 to your computer and use it in GitHub Desktop.
Save sdboyer/b482d1489311c6fd97c9281be65b1752 to your computer and use it in GitHub Desktop.
sketch of genericized modular generator framework
type Generator[T any] interface {
// dear go generics why do you have to suck so much (union not allowed because interfaces contain methods)
OneToOne[T] | OneToMany[T] | ManyToOne[T] | ManyToMany[T]
}
// Takes one T and makes one file
//
// replaces KindGenStep
type OneToOne[T any] interface {
// Name returns the name of the generator. For use in error output.
Name() string
// Generate takes a kindsys.SomeDecl and generates a single file. A nil, nil
// return indicates the generator has nothing to do for the provided kind.
Generate(T) (*GeneratedFile, error)
}
// Takes one T and makes many files
//
// perfect for when we need to e.g. generate a types file for the latest in each
// major version
type OneToMany[T any] interface {
// Name returns the name of the generator. For use in error output.
Name() string
// Generate takes a kindsys.SomeDecl and generates a single file. A nil, nil
// return indicates the generator has nothing to do for the provided kind.
Generate(T) ([]*GeneratedFile, error)
}
// Takes many Ts and makes one file
//
// replaces AggregateKindGenStep
type ManyToOne[T any] interface {
// Name returns the name of the generator. For use in error output.
Name() string
// Generate takes a kindsys.SomeDecl and generates a single file. A nil, nil
// return indicates the generator has nothing to do for the provided kind.
Generate([]T) (*GeneratedFile, error)
}
// Takes many Ts and makes many files
//
// basically what you get with a collection of generators, like below
type ManyToMany[T any] interface {
// Name returns the name of the generator. For use in error output.
Name() string
// Generate takes a kindsys.SomeDecl and generates a single file. A nil, nil
// return indicates the generator has nothing to do for the provided kind.
Generate([]T) ([]*GeneratedFile, error)
}
// A set of generators that should be executed over some input in sequence
type GeneratorSet[T any] struct {
Generators []Generator[T]
PostProcessors []func(*GeneratedFile) (*GeneratedFile, error)
}
var _ ManyToMany[any] = GeneratorSet[any]
// AdaptGenerator adapts a Generator that expects an input of type F to one
// expecting an input of type T by way of a mapfn that tranforms an F into a T.
func AdaptGenerator[F, T any](gen Generator[F], mapfn func(f F) T) Generator[T] {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment