API: Added reactions into rate limit parsers
This commit is contained in:
parent
5acf01d984
commit
f3b4362ada
|
@ -0,0 +1,64 @@
|
|||
package rate
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf16"
|
||||
)
|
||||
|
||||
func StringIsEmojiOnly(emoji string) bool {
|
||||
runes := []rune(emoji)
|
||||
// Slice of runes is 2, since some emojis have 2 runes.
|
||||
switch len(runes) {
|
||||
case 0:
|
||||
return false
|
||||
case 1, 2:
|
||||
return EmojiRune(runes[0])
|
||||
// case 2:
|
||||
// return EmojiRune(runes[0]) && EmojiRune(runes[1])
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func StringIsCustomEmoji(emoji string) bool {
|
||||
parts := strings.Split(emoji, ":")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate ID
|
||||
_, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate name, shouldn't have whitespaces
|
||||
if strings.ContainsRune(parts[0], ' ') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var surrogates = [...][2]rune{ // [0] from, [1] to
|
||||
{utf16.DecodeRune(0xD83C, 0xD000), utf16.DecodeRune(0xD83C, 0xDFFF)},
|
||||
{utf16.DecodeRune(0xD83E, 0xD000), utf16.DecodeRune(0xD83E, 0xDFFF)},
|
||||
{utf16.DecodeRune(0xD83F, 0xD000), utf16.DecodeRune(0xD83F, 0xDFFF)},
|
||||
}
|
||||
|
||||
func EmojiRune(r rune) bool {
|
||||
b := r == '\u00a9' || r == '\u00ae' ||
|
||||
(r >= '\u2000' && r <= '\u3300')
|
||||
if b {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, surrogate := range surrogates {
|
||||
if surrogate[0] <= r && r <= surrogate[1] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// +build unit
|
||||
|
||||
package rate
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestEmojiRuneParsing(t *testing.T) {
|
||||
var emojis = []string{
|
||||
"🏑",
|
||||
"❄️",
|
||||
"🤲🏿",
|
||||
}
|
||||
|
||||
var notEmojis = []string{
|
||||
"🏃🏿🏃🏿", // dual emojis
|
||||
"te", // not emoji
|
||||
}
|
||||
|
||||
for i, emoji := range emojis {
|
||||
if !StringIsEmojiOnly(emoji) {
|
||||
t.Fatal(i, "is an emoji, function returned false")
|
||||
}
|
||||
}
|
||||
|
||||
for i, not := range notEmojis {
|
||||
if StringIsEmojiOnly(not) {
|
||||
t.Fatal(i, "is not an emoji, function returned true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmojiCustomParsing(t *testing.T) {
|
||||
var emojis = []string{
|
||||
"emoji_thing:213131141",
|
||||
"StareNeutral:612368399732965376",
|
||||
}
|
||||
|
||||
for i, emoji := range emojis {
|
||||
if !StringIsCustomEmoji(emoji) {
|
||||
t.Fatal(i, "is a custom emoji, fn returned false")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,9 +29,22 @@ func ParseBucketKey(path string) string {
|
|||
|
||||
// we need to remove IDs from these
|
||||
for ; skip < len(parts); skip++ {
|
||||
// Check if it's a number:
|
||||
if _, err := strconv.Atoi(parts[skip]); err == nil {
|
||||
// is a number, DELET
|
||||
parts[skip] = ""
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if it's an emoji:
|
||||
if StringIsEmojiOnly(parts[skip]) {
|
||||
parts[skip] = ""
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if it's a custom emoji:
|
||||
if StringIsCustomEmoji(parts[skip]) {
|
||||
parts[skip] = ""
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,24 @@ import "testing"
|
|||
|
||||
func TestBucketKey(t *testing.T) {
|
||||
var tests = [][2]string{
|
||||
{"/guilds/123123/messages", "/guilds/123123/messages"},
|
||||
{"/guilds/123123/", "/guilds/123123/"},
|
||||
{"/channels/123131231", "/channels/123131231"},
|
||||
{"/channels/123123/message/123456", "/channels/123123/message/"},
|
||||
{"/guilds/123123/messages",
|
||||
"/guilds/123123/messages"},
|
||||
{"/guilds/123123/",
|
||||
"/guilds/123123/"},
|
||||
{"/channels/123131231",
|
||||
"/channels/123131231"},
|
||||
{"/channels/123123/message/123456",
|
||||
"/channels/123123/message/"},
|
||||
{"/user/123123", "/user/"},
|
||||
{"/user/123123/", "/user//"}, // not sure about this
|
||||
// Not sure about this:
|
||||
{"/user/123123/", "/user//"},
|
||||
{"/channels/1/messages/1/reactions/🤔/@me",
|
||||
"/channels/1/messages//reactions//@me"},
|
||||
{"/channels/1/messages/2/reactions/thonk:123123/@me",
|
||||
"/channels/1/messages//reactions//@me"},
|
||||
// Actual URL:
|
||||
{"/channels/486833611564253186/messages/540519319814275089/reactions/🥺/@me",
|
||||
"/channels/486833611564253186/messages//reactions//@me"},
|
||||
}
|
||||
|
||||
for _, conds := range tests {
|
||||
|
|
|
@ -3,7 +3,8 @@ package arguments
|
|||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"unicode/utf16"
|
||||
|
||||
"github.com/diamondburned/arikawa/api/rate"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -56,7 +57,7 @@ func (e Emoji) URL() string {
|
|||
|
||||
func (e *Emoji) Parse(arg string) error {
|
||||
// Check if Unicode emoji
|
||||
if stringIsEmojiOnly(arg) {
|
||||
if rate.StringIsEmojiOnly(arg) {
|
||||
e.ID = arg
|
||||
e.Custom = false
|
||||
|
||||
|
@ -76,35 +77,3 @@ func (e *Emoji) Parse(arg string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func stringIsEmojiOnly(emoji string) bool {
|
||||
runes := []rune(emoji)
|
||||
// Slice of runes is 2, since some emojis have 2 runes.
|
||||
if len(runes) > 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return emojiRune(runes[0])
|
||||
}
|
||||
|
||||
var surrogates = [...][2]rune{ // [0] from, [1] to
|
||||
{utf16.DecodeRune(0xD83C, 0xD000), utf16.DecodeRune(0xD83C, 0xDFFF)},
|
||||
{utf16.DecodeRune(0xD83E, 0xD000), utf16.DecodeRune(0xD83E, 0xDFFF)},
|
||||
{utf16.DecodeRune(0xD83F, 0xD000), utf16.DecodeRune(0xD83F, 0xDFFF)},
|
||||
}
|
||||
|
||||
func emojiRune(r rune) bool {
|
||||
b := r == '\u00a9' || r == '\u00ae' ||
|
||||
(r >= '\u2000' && r <= '\u3300')
|
||||
if b {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, surrogate := range surrogates {
|
||||
if surrogate[0] <= r && r <= surrogate[1] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -2,31 +2,6 @@ package arguments
|
|||
|
||||
import "testing"
|
||||
|
||||
func TestEmojiRuneParsing(t *testing.T) {
|
||||
var emojis = []string{
|
||||
"🏑",
|
||||
"❄️",
|
||||
"🤲🏿",
|
||||
}
|
||||
|
||||
var notEmojis = []string{
|
||||
"🏃🏿🏃🏿", // dual emojis
|
||||
"te", // not emoji
|
||||
}
|
||||
|
||||
for i, emoji := range emojis {
|
||||
if !stringIsEmojiOnly(emoji) {
|
||||
t.Fatal(i, "is an emoji, function returned false")
|
||||
}
|
||||
}
|
||||
|
||||
for i, not := range notEmojis {
|
||||
if stringIsEmojiOnly(not) {
|
||||
t.Fatal(i, "is not an emoji, function returned true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmojiRune(t *testing.T) {
|
||||
const emoji = "💩"
|
||||
|
||||
|
|
Loading…
Reference in New Issue