foxcord/Foxcord/Rest/Rate/BucketKeyUtils.cs
2024-09-03 00:07:12 +02:00

65 lines
No EOL
1.7 KiB
C#

using System.Text;
namespace Foxcord.Rest.Rate;
// All of this code is taken from Arikawa:
// https://github.com/diamondburned/arikawa/blob/v3/api/rate/rate.go
internal static class BucketKeyUtils
{
private static readonly string[] MajorRootPaths = ["channels", "guilds"];
internal static string Parse(string path)
{
path = path.Split("?", 2)[0];
var parts = path.Split("/");
if (parts.Length == 0) return path;
parts = parts.Skip(1).ToArray();
var skip = 0;
if (MajorRootPaths.Contains(parts[0])) skip = 2;
skip++;
for (; skip < parts.Length; skip += 2)
{
if (long.TryParse(parts[skip], out _) || StringIsEmojiOnly(parts[skip]) || StringIsCustomEmoji(parts[skip]))
parts[skip] = "";
}
path = string.Join("/", parts);
return $"/{path}";
}
private static bool StringIsCustomEmoji(string emoji)
{
var parts = emoji.Split(":");
if (parts.Length != 2) return false;
if (!long.TryParse(parts[1], out _)) return false;
if (parts[0].Contains(' ')) return false;
return true;
}
private static bool StringIsEmojiOnly(string emoji)
{
var runes = emoji.EnumerateRunes().ToArray();
switch (runes.Length)
{
case 0:
return false;
case 1:
case 2:
return EmojiRune(runes[0]);
}
return false;
}
private static bool EmojiRune(Rune r)
{
if (r == new Rune('\u00a9') || r == new Rune('\u00ae') ||
(r >= new Rune('\u2000') && r <= new Rune('\u3300'))) return true;
return false;
}
}