main.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package main
  2. import (
  3. "bytes"
  4. "go/format"
  5. "go/parser"
  6. "go/token"
  7. "io/ioutil"
  8. "log"
  9. "path/filepath"
  10. "regexp"
  11. "sort"
  12. "strings"
  13. "text/template"
  14. )
  15. var eventHandlerTmpl = template.Must(template.New("eventHandler").Funcs(template.FuncMap{
  16. "constName": constName,
  17. "isDiscordEvent": isDiscordEvent,
  18. "privateName": privateName,
  19. }).Parse(`// Code generated by \"eventhandlers\"; DO NOT EDIT
  20. // See events.go
  21. package discordgo
  22. // Following are all the event types.
  23. // Event type values are used to match the events returned by Discord.
  24. // EventTypes surrounded by __ are synthetic and are internal to DiscordGo.
  25. const ({{range .}}
  26. {{privateName .}}EventType = "{{constName .}}"{{end}}
  27. )
  28. {{range .}}
  29. // {{privateName .}}EventHandler is an event handler for {{.}} events.
  30. type {{privateName .}}EventHandler func(*Session, *{{.}})
  31. // Type returns the event type for {{.}} events.
  32. func (eh {{privateName .}}EventHandler) Type() string {
  33. return {{privateName .}}EventType
  34. }
  35. {{if isDiscordEvent .}}
  36. // New returns a new instance of {{.}}.
  37. func (eh {{privateName .}}EventHandler) New() interface{} {
  38. return &{{.}}{}
  39. }{{end}}
  40. // Handle is the handler for {{.}} events.
  41. func (eh {{privateName .}}EventHandler) Handle(s *Session, i interface{}) {
  42. if t, ok := i.(*{{.}}); ok {
  43. eh(s, t)
  44. }
  45. }
  46. {{end}}
  47. func handlerForInterface(handler interface{}) EventHandler {
  48. switch v := handler.(type) {
  49. case func(*Session, interface{}):
  50. return interfaceEventHandler(v){{range .}}
  51. case func(*Session, *{{.}}):
  52. return {{privateName .}}EventHandler(v){{end}}
  53. }
  54. return nil
  55. }
  56. func init() { {{range .}}{{if isDiscordEvent .}}
  57. registerInterfaceProvider({{privateName .}}EventHandler(nil)){{end}}{{end}}
  58. }
  59. `))
  60. func main() {
  61. var buf bytes.Buffer
  62. dir := filepath.Dir(".")
  63. fs := token.NewFileSet()
  64. parsedFile, err := parser.ParseFile(fs, "events.go", nil, 0)
  65. if err != nil {
  66. log.Fatalf("warning: internal error: could not parse events.go: %s", err)
  67. return
  68. }
  69. names := []string{}
  70. for object := range parsedFile.Scope.Objects {
  71. names = append(names, object)
  72. }
  73. sort.Strings(names)
  74. eventHandlerTmpl.Execute(&buf, names)
  75. src, err := format.Source(buf.Bytes())
  76. if err != nil {
  77. log.Println("warning: internal error: invalid Go generated:", err)
  78. src = buf.Bytes()
  79. }
  80. err = ioutil.WriteFile(filepath.Join(dir, strings.ToLower("eventhandlers.go")), src, 0644)
  81. if err != nil {
  82. log.Fatal(buf, "writing output: %s", err)
  83. }
  84. }
  85. var constRegexp = regexp.MustCompile("([a-z])([A-Z])")
  86. func constCase(name string) string {
  87. return strings.ToUpper(constRegexp.ReplaceAllString(name, "${1}_${2}"))
  88. }
  89. func isDiscordEvent(name string) bool {
  90. switch {
  91. case name == "Connect", name == "Disconnect", name == "Event", name == "RateLimit", name == "Interface":
  92. return false
  93. default:
  94. return true
  95. }
  96. }
  97. func constName(name string) string {
  98. if !isDiscordEvent(name) {
  99. return "__" + constCase(name) + "__"
  100. }
  101. return constCase(name)
  102. }
  103. func privateName(name string) string {
  104. return strings.ToLower(string(name[0])) + name[1:]
  105. }