Skip to content

Commit

Permalink
better option handling, new f builders
Browse files Browse the repository at this point in the history
  • Loading branch information
Karitham committed Dec 25, 2021
1 parent 43126b8 commit 1140fe9
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 35 deletions.
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
# corde

corde is a discord webhook callback API wrapper.
It's nowhere near prod-ready, but it's honestly usable, and it's open to contributions.
[![report card](https://goreportcard.com/badge/github.com/Karitham/corde)](https://goreportcard.com/report/github.com/Karitham/corde)
[![badge](https://pkg.go.dev/badge/github.com/Karitham/corde)](https://pkg.go.dev/github.com/Karitham/corde)

---

corde is a discord webhook callback API wrapper. It aims to have an high level API to simplify the user's life as much as possible.

It contains many functions to help write as clean and concise code as possible, such as `f` suffixed functions which act like `Sprintf`.

It also has builders of some kinds, such as embed and response builders, which make error handling and responding a breeze.

All those don't hinder the fact that you can use corde with as much control as you want.

Be aware that breaking changes will happen as of now, at least until v1.

## Examples

The most basic one is [**bongo**](_example/bongo/main.go)

Then comes [**todo**](_example/todo/) that shows off subcommands routing and options

And then we have [**moderate-myself**](_example/moderate-myself/main.go) which is able to show and delete currently available commands.
It demonstrates the usage of components such as buttons.

Corde is also actively used to rewrite and develop another discord bot of mine called [**WaifuBot**](https://github.com/Karitham/WaifuBot/) (for now see the corde branch)

## Install

```sh
go get github.com/Karitham/corde
```

## Why

Having used most go discord libs available, I wanted something very lightweight, that could just run on a lambda.
The common libs out there didn't really fit that purpose, and neither did they implement the webhook callback API available.
Having used most go discord libs available, I wanted something very lightweight yet high-level, that could just run on a lambda without state, caching or long start-up times.

Corde has a single dependency as of yet, and it's just a codegen utility.

It's from that usecase that Corde is born.
The common libs out there didn't really fit that purpose, and neither did they implement the webhook callback API available.

## Usage
It's from that usecase that corde is born.

See [todo](_example/todo/) for an example usage.
Corde means *rope* in french, because discord's API inspires exactly that /s
8 changes: 1 addition & 7 deletions _example/moderate-myself/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,7 @@ func list(m *corde.Mux, g func(*corde.CommandsOpt)) func(corde.ResponseWriter, *

func rm(m *corde.Mux, g func(*corde.CommandsOpt)) func(corde.ResponseWriter, *corde.Interaction) {
return func(w corde.ResponseWriter, i *corde.Interaction) {
n, ok := i.Data.Options["name"]
if !ok {
w.Respond(
corde.NewResp().Content("Please enter an actual command name.").Ephemeral().B(),
)
return
}
n := i.Data.Options.String("name")

c, _ := m.GetCommands(g)
for _, c := range c {
Expand Down
19 changes: 3 additions & 16 deletions _example/todo/todo.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,8 @@ type todo struct {
}

func (t *todo) addHandler(w corde.ResponseWriter, i *corde.Interaction) {
value, ok := i.Data.Options["value"].(string)
if !ok {
w.Respond(corde.NewResp().Content("no value provided").Ephemeral().B())
return
}

name, ok := i.Data.Options["name"].(string)
if !ok {
w.Respond(corde.NewResp().Content("no name provided").Ephemeral().B())
return
}
value := i.Data.Options.String("value")
name := i.Data.Options.String("name")

t.mu.Lock()
defer t.mu.Unlock()
Expand Down Expand Up @@ -67,11 +58,7 @@ func (t *todo) removeHandler(w corde.ResponseWriter, i *corde.Interaction) {
t.mu.Lock()
defer t.mu.Unlock()

name, ok := i.Data.Options["name"].(string)
if !ok {
w.Respond(corde.NewResp().Content("no name provided").Ephemeral().B())
return
}
name := i.Data.Options.String("name")

delete(t.list, name)
w.Respond(corde.NewResp().Content("deleted todo").Ephemeral().B())
Expand Down
12 changes: 12 additions & 0 deletions embed-builder.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package corde

import "fmt"

// Embed builder
// https://regex101.com/r/gmVH2A/3
type EmbedB struct {
Expand Down Expand Up @@ -40,11 +42,21 @@ func (b *EmbedB) Title(s string) *EmbedB {
return b
}

func (b *EmbedB) Titlef(format string, a ...any) *EmbedB {
b.Embed.Title = fmt.Sprintf(format, a...)
return b
}

func (b *EmbedB) Description(s string) *EmbedB {
b.Embed.Description = s
return b
}

func (b *EmbedB) Descriptionf(format string, a ...any) *EmbedB {
b.Embed.Description = fmt.Sprintf(format, a...)
return b
}

func (b *EmbedB) Thumbnail(i Image) *EmbedB {
b.Embed.Thumbnail = i
return b
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/Karitham/corde

go 1.18

require github.com/karitham/go-genial v0.2.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/karitham/go-genial v0.2.0 h1:AHb2iBbzOBS8kc3E0QiZR3Z6txdBS9u0IDhGGketskE=
github.com/karitham/go-genial v0.2.0/go.mod h1:HBN0CvV0hsPCMegF7wvmUK3l8OnNzs8XVxt350NI5eE=
56 changes: 56 additions & 0 deletions interaction-opt.gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// retrieve options from interaction data
package corde

// String returns the option with key k of type string
func (o OptionsInteractions) String(k string) string {
v, _ := o[k].(string)
return v
}

// Int returns the option with key k of type int
func (o OptionsInteractions) Int(k string) int {
v, _ := o[k].(int)
return v
}

// Int64 returns the option with key k of type int64
func (o OptionsInteractions) Int64(k string) int64 {
v, _ := o[k].(int64)
return v
}

// Uint returns the option with key k of type uint
func (o OptionsInteractions) Uint(k string) uint {
v, _ := o[k].(uint)
return v
}

// Uint64 returns the option with key k of type uint64
func (o OptionsInteractions) Uint64(k string) uint64 {
v, _ := o[k].(uint64)
return v
}

// Float32 returns the option with key k of type float32
func (o OptionsInteractions) Float32(k string) float32 {
v, _ := o[k].(float32)
return v
}

// Float64 returns the option with key k of type float64
func (o OptionsInteractions) Float64(k string) float64 {
v, _ := o[k].(float64)
return v
}

// Bool returns the option with key k of type bool
func (o OptionsInteractions) Bool(k string) bool {
v, _ := o[k].(bool)
return v
}

// Snowflake returns the option with key k of type Snowflake
func (o OptionsInteractions) Snowflake(k string) Snowflake {
v, _ := o[k].(Snowflake)
return v
}
5 changes: 0 additions & 5 deletions interaction-responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,3 @@ type Image struct {
type MessageReference struct {
MessageID string `json:"message_id"`
}

// Opt returns a ptr to the type
func Opt[T any](t T) *T {
return &t
}
59 changes: 59 additions & 0 deletions internal/cmd/gen-opt/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"flag"
"fmt"
"os"
"strings"

genial "github.com/karitham/go-genial"
)

var types = []string{
"string",
"int",
"int64",
"uint",
"uint64",
"float32",
"float64",
"bool",
"Snowflake",
}

var body string = ` v, _ := o[k].(%s)
return v
`

var file = flag.String("file", "../../../interaction-opt.gen.go", "output file")

//go:generate go run .
func main() {
flag.Parse()

p := &genial.PackageB{}
p.Name("corde").Comment("retrieve options from interaction data")

for _, t := range types {
f := &genial.FuncB{}

name := strings.Title(t)

f.Receiver(genial.Parameter{Name: "o", Type: "OptionsInteractions"}).
Comment(fmt.Sprintf("%s returns the option with key k of type %s", name, t)).
Name(name).
Parameters(genial.Parameter{
Name: "k",
Type: "string",
}).
ReturnTypes(genial.Parameter{
Type: t,
})

f.Write([]byte(fmt.Sprintf(body, t)))

p.Declarations(f)
}

os.WriteFile(*file, []byte(p.String()), 0644)
}

0 comments on commit 1140fe9

Please sign in to comment.