Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
diamondburned
GitHub Repository: diamondburned/gtkcord4
Path: blob/main/internal/messages/key.go
366 views
1
package messages
2
3
import (
4
"encoding/base64"
5
"fmt"
6
"log"
7
"math/rand"
8
"strconv"
9
"strings"
10
"sync/atomic"
11
"time"
12
13
"github.com/diamondburned/arikawa/v3/discord"
14
"github.com/diamondburned/gotk4/pkg/gtk/v4"
15
)
16
17
type messageKey string
18
19
const (
20
messageKeyEventPrefix = "event"
21
messageKeyLocalPrefix = "local"
22
)
23
24
func messageKeyRow(row *gtk.ListBoxRow) messageKey {
25
if row == nil {
26
return ""
27
}
28
29
name := row.Name()
30
if !strings.Contains(name, ":") {
31
log.Panicf("row name %q not a messageKey", name)
32
}
33
34
return messageKey(name)
35
}
36
37
// messageKeyID returns the messageKey for a message ID.
38
func messageKeyID(id discord.MessageID) messageKey {
39
return messageKey(messageKeyEventPrefix + ":" + string(id.String()))
40
}
41
42
var (
43
messageKeyLocalInc uint64
44
messageNonceRandom = rand.New(rand.NewSource(time.Now().UnixNano()))
45
)
46
47
// messageKeyLocal creates a new local messageKey that will never collide with
48
// server events.
49
func messageKeyLocal() messageKey {
50
inc := atomic.AddUint64(&messageKeyLocalInc, 1)
51
num := strconv.FormatUint(inc, 32)
52
53
var rand [8]byte
54
messageNonceRandom.Read(rand[:])
55
prefix := base64.RawStdEncoding.EncodeToString(rand[:])
56
57
return messageKey(fmt.Sprintf(
58
"%s:%s-%s", messageKeyLocalPrefix, prefix, num,
59
))
60
}
61
62
// messageKeyNonce creates a new messageKey from the given nonce.
63
func messageKeyNonce(nonce string) messageKey {
64
return messageKey(messageKeyLocalPrefix + ":" + nonce)
65
}
66
67
func (k messageKey) parts() (typ, val string) {
68
parts := strings.SplitN(string(k), ":", 2)
69
if len(parts) != 2 {
70
log.Panicf("invalid messageKey %q", parts)
71
}
72
return parts[0], parts[1]
73
}
74
75
// ID takes the message ID from the message key. If the key doesn't hold an
76
// event ID, then it panics.
77
func (k messageKey) ID() discord.MessageID {
78
t, v := k.parts()
79
if t != messageKeyEventPrefix {
80
panic("EventID called on non-event message key")
81
}
82
83
u, err := discord.ParseSnowflake(v)
84
if err != nil {
85
panic("invalid snowflake stored: " + err.Error())
86
}
87
88
return discord.MessageID(u)
89
}
90
91
// Nonce returns a nonce from the message key. The nonce has a static size. If
92
// the key doesn't hold a local value, then it panics.
93
func (k messageKey) Nonce() string {
94
t, v := k.parts()
95
if t != messageKeyLocalPrefix {
96
panic("Nonce called on non-local message key")
97
}
98
return v
99
}
100
101
func (k messageKey) IsEvent() bool {
102
typ, _ := k.parts()
103
return typ == messageKeyEventPrefix
104
}
105
106
func (k messageKey) IsLocal() bool {
107
typ, _ := k.parts()
108
return typ == messageKeyLocalPrefix
109
}
110
111