Skip to content

Commit

Permalink
autogen restbuilder setter methods + WIP on user REST methods
Browse files Browse the repository at this point in the history
  • Loading branch information
andersfylling committed Mar 2, 2019
1 parent 31e083e commit d29a3b2
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 138 deletions.
27 changes: 2 additions & 25 deletions auditlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,35 +310,12 @@ func (c *client) GetGuildAuditLogs(guildID snowflake.ID, flags ...Flag) (builder
return builder
}

// guildAuditLogsBuilder for building the GetGuildAuditLogs request
// guildAuditLogsBuilder for building the GetGuildAuditLogs request.
//generate-rest-params: user_id:Snowflake, action_type:uint, before:Snowflake, limit:int,
type guildAuditLogsBuilder struct {
r RESTBuilder
}

// UserID filter the log for a user id
func (b *guildAuditLogsBuilder) UserID(id snowflake.ID) *guildAuditLogsBuilder {
b.r.queryParam("user_id", id)
return b
}

// ActionType the type of audit log event
func (b *guildAuditLogsBuilder) ActionType(action uint) *guildAuditLogsBuilder {
b.r.queryParam("action_type", action)
return b
}

// Before filter the log before a certain entry id
func (b *guildAuditLogsBuilder) Before(id snowflake.ID) *guildAuditLogsBuilder {
b.r.queryParam("before", id)
return b
}

// Before filter the log before a certain entry id
func (b *guildAuditLogsBuilder) Limit(limit int) *guildAuditLogsBuilder {
b.r.queryParam("limit", limit)
return b
}

func (b *guildAuditLogsBuilder) Execute() (log *AuditLog, err error) {
// TODO: support caching of audit log entries. So we only fetch those we don't have.
var v interface{}
Expand Down
6 changes: 3 additions & 3 deletions auditlog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,19 @@ func TestAuditLogParams(t *testing.T) {

s := "438543957"
ss, _ := snowflake.GetSnowflake(s)
params.UserID(ss)
params.SetUserID(ss)
wants = "?user_id=" + s
verifyQueryString(t, params.r.urlParams, wants)

params.ActionType(6)
params.SetActionType(6)
wants += "&action_type=6"
wantsAlternative := "?action_type=6&user_id=" + s
got := params.r.urlParams.URLQueryString()
if !(wants == got || wantsAlternative == got) {
t.Errorf("incorrect query param string. Got '%s', wants '%s' or '%s'", params.r.urlParams.URLQueryString(), wants, wantsAlternative)
}

params.ActionType(0)
params.SetActionType(0)
wants = "?user_id=" + s + "&action_type=0"
wantsAlternative = "?action_type=0&user_id=" + s
got = params.r.urlParams.URLQueryString()
Expand Down
8 changes: 2 additions & 6 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,12 @@ func (c *client) DisconnectOnInterrupt() (err error) {
// When a error happens you can terminate the application without worries.
func (c *client) StayConnectedUntilInterrupted() (err error) {
if err = c.Connect(); err != nil {
c.log.Error(err)
return err
}

if err = c.DisconnectOnInterrupt(); err != nil {
c.log.Error(err)
return err
}

Expand Down Expand Up @@ -945,12 +947,6 @@ func (c *client) ModifyGuildRolePositions(guildID Snowflake, params []ModifyGuil
return
}

// ModifyGuildRole .
func (c *client) ModifyGuildRole(guildID, roleID Snowflake, params *ModifyGuildRoleParams, flags ...Flag) (ret *Role, err error) {
ret, err = ModifyGuildRole(c.req, guildID, roleID, params)
return
}

// DeleteGuildRole .
func (c *client) DeleteGuildRole(guildID, roleID Snowflake, flags ...Flag) (err error) {
err = DeleteGuildRole(c.req, guildID, roleID)
Expand Down
3 changes: 2 additions & 1 deletion event_demultiplexer_gen.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package disgord

// Warning: This file has been automatically generated by generate/events/main.go
// Do NOT make changes here, instead adapt events.go and event/events.go and run go generate
// DO NOT EDIT! This file is overwritten at "go generate", instead adapt events.go
// and event/events.go and run go generate

import (
"context"
Expand Down
3 changes: 2 additions & 1 deletion events_gen.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package disgord

// Warning: This file has been automatically generated by generate/events/main.go
// Do NOT make changes here, instead adapt events.go and event/events.go and run go generate
// DO NOT EDIT! This file is overwritten at "go generate", instead adapt events.go and
// event/events.go and run go generate

import (
"context"
Expand Down
3 changes: 2 additions & 1 deletion generate/events/event_demultiplexer.gotpl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package disgord

// Warning: This file has been automatically generated by generate/events/main.go
// Do NOT make changes here, instead adapt events.go and event/events.go and run go generate
// DO NOT EDIT! This file is overwritten at "go generate", instead adapt events.go
// and event/events.go and run go generate

import (
"context"
Expand Down
3 changes: 2 additions & 1 deletion generate/events/events.gotpl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package disgord

// Warning: This file has been automatically generated by generate/events/main.go
// Do NOT make changes here, instead adapt events.go and event/events.go and run go generate
// DO NOT EDIT! This file is overwritten at "go generate", instead adapt events.go and
// event/events.go and run go generate

import (
"context"
Expand Down
121 changes: 104 additions & 17 deletions generate/restbuilders/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ func main() {
makeFile(builders, "generate/restbuilders/methods.gotpl", "restbuilders_gen.go")
}

type builder struct {
name string
fieldName string
}

func (e builder) String() string {
return e.name
type tuple struct {
Name string
MethodName string
Type string
}

func (e builder) FieldName() string {
return e.fieldName
type builder struct {
Name string
FieldName string
pos token.Pos
Params []tuple
}

func getAllRESTBuilders(filename string) (builders []*builder) {
Expand All @@ -50,13 +50,14 @@ func getAllRESTBuilders(filename string) (builders []*builder) {

// Try to find all event structs defined in the file
const RESTBuilder = "RESTBuilder"
const RESTBuilder2 = "*RESTBuilder"
for name, item := range file.Scope.Objects {
// Only continue if we are dealing with a type declaration
if item.Kind != ast.Typ {
continue
}

// must contain Builder in it's name / suffix
// must contain Builder in it's Name / suffix
if !strings.HasSuffix(name, "Builder") || name == RESTBuilder {
continue
}
Expand All @@ -74,9 +75,9 @@ func getAllRESTBuilders(filename string) (builders []*builder) {
var isRESTBuilder bool
var fieldName string
for _, field := range fields {
if id, ok := field.Type.(*ast.Ident); ok && id.Name == RESTBuilder {
if id, ok := field.Type.(*ast.Ident); ok && (id.Name == RESTBuilder || id.Name == RESTBuilder2) {
if len(field.Names) == 0 {
panic("" + filename + "#" + name + " must specify a field name for the embedded struct " + RESTBuilder)
panic("" + filename + "#" + name + " must specify a field Name for the embedded struct " + RESTBuilder)
}
fieldName = field.Names[0].Name
isRESTBuilder = true
Expand All @@ -87,20 +88,99 @@ func getAllRESTBuilders(filename string) (builders []*builder) {
if !isRESTBuilder {
continue
}

//
//if genDecl, ok := item.(*ast.GenDecl); ok {
// fmt.Printf("%+v\n", genDecl)
//}
//if typeDecl.Doc != nil {
// fmt.Printf("%+v\n", typeDecl.Doc.List)
//}

pos := item.Pos()
if pos > 300 {
pos -= 300 // magic
} else {
pos = 0
}
builders = append(builders, &builder{
name: name,
fieldName: fieldName,
Name: name,
FieldName: fieldName,
pos: pos,
})
}

// Read the comment to check for generate instructions
fileComments, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.ParseComments)
if err != nil {
panic(err)
}
var pp int
const genPrefix = "//generate-rest-params: "
for _, item := range fileComments.Comments {
if len(builders) == pp {
break
}

if item.Pos() < builders[pp].pos {
continue
}

for i := range item.List {
comment := item.List[i].Text
if !strings.HasPrefix(comment, genPrefix) {
continue
}
var start = len(genPrefix)
var end int
if strings.HasSuffix(comment, ",") {
end = len(comment) - 1
} else {
end = len(comment)
}
paramsStr := comment[start:end]
params := strings.Split(paramsStr, ", ")

tuples := make([]tuple, 0, len(params))
for j := range params {
param := strings.Split(params[j], ":")
name := param[0]
typ := param[1]
methodName := jsonNameToMethodName(name)
tuples = append(tuples, tuple{
MethodName: methodName,
Name: name,
Type: typ,
})
}
builders[pp].Params = tuples
pp++
}
}

sort.Slice(builders, func(i, j int) bool {
return builders[i].name < builders[j].name
return builders[i].Name < builders[j].Name
})

return builders
}

func jsonNameToMethodName(name string) string {
words := strings.Split(name, "_")
var methodName string
for i := range words {
if words[i] == "id" {
methodName += "ID"
} else {
methodName += Capitalize(words[i])
}
}
return methodName
}

func Capitalize(s string) string {
return strings.ToUpper(s[0:1]) + s[1:]
}

func getFiles(path string) (files []string, err error) {
var results []string
err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
Expand All @@ -127,8 +207,15 @@ func getFiles(path string) (files []string, err error) {
}

func makeFile(builders []*builder, tplFile, target string) {
fMap := template.FuncMap{
"ToUpper": strings.ToUpper,
"ToLower": strings.ToLower,
"Capitalize": Capitalize,
"Decapitalize": func(s string) string { return strings.ToLower(s[0:1]) + s[1:] },
}

// Open & parse our template
tpl := template.Must(template.New(path.Base(tplFile)).ParseFiles(tplFile))
tpl := template.Must(template.New(path.Base(tplFile)).Funcs(fMap).ParseFiles(tplFile))

// Execute the template, inserting all the event information
var b bytes.Buffer
Expand Down
29 changes: 18 additions & 11 deletions generate/restbuilders/methods.gotpl
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
package disgord

// Warning: This file has been automatically generated by generate/restbuilders/main.go
// Do _NOT_ make changes here!
// DO NOT EDIT! This file is overwritten at "go generate"
// This file holds all the basic RESTBuilder methods a builder is expected to.

{{ range . }}
{{ range $builder := . }}

// IgnoreCache will not fetch the data from the cache if available, and always execute a
// a REST request. However, the response will always update the cache to keep it synced.
func (b *{{.}}) IgnoreCache() *{{.}} {
b.{{ .FieldName }}.IgnoreCache()
func (b *{{$builder.Name}}) IgnoreCache() *{{$builder.Name}} {
b.{{ $builder.FieldName }}.IgnoreCache()
return b
}

// CancelOnRatelimit will disable waiting if the request is rate limited by Discord.
func (b *{{.}}) CancelOnRatelimit() *{{.}} {
b.{{ .FieldName }}.CancelOnRatelimit()
func (b *{{$builder.Name}}) CancelOnRatelimit() *{{$builder.Name}} {
b.{{ $builder.FieldName }}.CancelOnRatelimit()
return b
}

// URLParam adds or updates an existing URL parameter.
// eg. URLParam("age", 34) will cause the URL `/test` to become `/test?age=34`
func (b *{{.}}) URLParam(name string, v interface{}) *{{.}} {
b.{{ .FieldName }}.queryParam(name, v)
func (b *{{$builder.Name}}) URLParam(name string, v interface{}) *{{$builder.Name}} {
b.{{ $builder.FieldName }}.queryParam(name, v)
return b
}

// Set adds or updates an existing a body parameter
// eg. Set("age", 34) will cause the body `{}` to become `{"age":34}`
func (b *{{.}}) Set(name string, v interface{}) *{{.}} {
b.{{ .FieldName }}.body[name] = v
func (b *{{$builder.Name}}) Set(name string, v interface{}) *{{$builder.Name}} {
b.{{ $builder.FieldName }}.body[name] = v
return b
}
{{end}}

{{ range $i, $p := .Params }}
func (b *{{$builder.Name}}) Set{{ $p.MethodName }}({{ $p.MethodName | Decapitalize }} {{ $p.Type }}) *{{$builder.Name}} {
b.{{ $builder.FieldName }}.param("{{ $p.Name }}", {{ $p.MethodName | Decapitalize }})
return b
}
{{ end }}
{{ end }}
Loading

0 comments on commit d29a3b2

Please sign in to comment.