main.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. // New returns a new instance of {{.}}.
  36. func (eh {{privateName .}}EventHandler) New() interface{} {
  37. return &{{.}}{}
  38. }
  39. // Handle is the handler for {{.}} events.
  40. func (eh {{privateName .}}EventHandler) Handle(s *Session, i interface{}) {
  41. if t, ok := i.(*{{.}}); ok {
  42. eh(s, t)
  43. }
  44. }
  45. {{end}}
  46. func handlerForInterface(handler interface{}) EventHandler {
  47. switch v := handler.(type) {
  48. case func(*Session, interface{}):
  49. return interfaceEventHandler(v){{range .}}
  50. case func(*Session, *{{.}}):
  51. return {{privateName .}}EventHandler(v){{end}}
  52. }
  53. return nil
  54. }
  55. func init() { {{range .}}{{if isDiscordEvent .}}
  56. registerInterfaceProvider({{privateName .}}EventHandler(nil)){{end}}{{end}}
  57. }
  58. `))
  59. func main() {
  60. var buf bytes.Buffer
  61. dir := filepath.Dir(".")
  62. fs := token.NewFileSet()
  63. parsedFile, err := parser.ParseFile(fs, "events.go", nil, 0)
  64. if err != nil {
  65. log.Fatalf("warning: internal error: could not parse events.go: %s", err)
  66. return
  67. }
  68. names := []string{}
  69. for object := range parsedFile.Scope.Objects {
  70. names = append(names, object)
  71. }
  72. sort.Strings(names)
  73. eventHandlerTmpl.Execute(&buf, names)
  74. src, err := format.Source(buf.Bytes())
  75. if err != nil {
  76. log.Println("warning: internal error: invalid Go generated:", err)
  77. src = buf.Bytes()
  78. }
  79. err = ioutil.WriteFile(filepath.Join(dir, strings.ToLower("eventhandlers.go")), src, 0644)
  80. if err != nil {
  81. log.Fatal(buf, "writing output: %s", err)
  82. }
  83. }
  84. var constRegexp = regexp.MustCompile("([a-z])([A-Z])")
  85. func constCase(name string) string {
  86. return strings.ToUpper(constRegexp.ReplaceAllString(name, "${1}_${2}"))
  87. }
  88. func isDiscordEvent(name string) bool {
  89. switch {
  90. case name == "Connect", name == "Disconnect", name == "Event", name == "RateLimit", name == "Interface":
  91. return false
  92. default:
  93. return true
  94. }
  95. }
  96. func constName(name string) string {
  97. if !isDiscordEvent(name) {
  98. return "__" + constCase(name) + "__"
  99. }
  100. return constCase(name)
  101. }
  102. func privateName(name string) string {
  103. return strings.ToLower(string(name[0])) + name[1:]
  104. }