Skip to content

Instantly share code, notes, and snippets.

@man0xff
Last active April 9, 2022 06:22
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 man0xff/9bcb48e077b67bb8286b9433e21b43e0 to your computer and use it in GitHub Desktop.
Save man0xff/9bcb48e077b67bb8286b9433e21b43e0 to your computer and use it in GitHub Desktop.
Universal way to generate some Go code from single description (like X-Macro in C).
// I was looking for some substitution for X-Macro C preprocessor trick (https://en.wikipedia.org/wiki/X_Macro).
// And this method copes with a problem in a lot more straightforward and powerful way.
// X-Macro version in C:
//
// #define SOME_STATES(_) \
// _(SOME_STATE_NEW, "NEW") \
// _(SOME_STATE_IN_PROGRESS, "IN_PROGRESS") \
// _(SOME_STATE_DONE, "DONE")
//
// #define X(name, ...) name,
// enum {
// SOME_STATES(X)
// };
// #undef X
some_states:
- name: SomeStateNew
val: SomeState = iota
text: NEW
- name: SomeStateInProgress
text: IN_PROGRESS
- name: SomeStateDone
text: DONE
package somepkg
//go:generate sh -c "gotpl some_state.tpl -f data.yaml | gofmt >some_state.gen.go"
// for debug use: go:generate sh -c "gotpl some_state.tpl -f data.yaml | tee /dev/stderr | gofmt >some_state.gen.go"
package somepkg
import "errors"
const (
{{- range .some_states}}
{{.name}} {{.val}}
{{- end}}
)
func (s SomeState) String() string {
switch s {
{{- range .some_states}}
case {{.name}}:
return "{{.text}}"
{{- end}}
}
return "<unknown>"
}
func Parse(s string) (SomeState, error) {
switch s {
{{- range .some_states}}
case "{{.text}}":
return {{.name}}, nil
{{- end}}
}
return SomeState(0), errors.New("unknown some state")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment