main.go 3.0 KB

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