github.com/diamondburned/arikawa/v2@v2.1.0/api/rate/emoji.go (about) 1 package rate 2 3 import ( 4 "strconv" 5 "strings" 6 "unicode/utf16" 7 ) 8 9 func StringIsEmojiOnly(emoji string) bool { 10 runes := []rune(emoji) 11 // Slice of runes is 2, since some emojis have 2 runes. 12 switch len(runes) { 13 case 0: 14 return false 15 case 1, 2: 16 return EmojiRune(runes[0]) 17 // case 2: 18 // return EmojiRune(runes[0]) && EmojiRune(runes[1]) 19 default: 20 return false 21 } 22 } 23 24 func StringIsCustomEmoji(emoji string) bool { 25 parts := strings.Split(emoji, ":") 26 if len(parts) != 2 { 27 return false 28 } 29 30 // Validate ID 31 _, err := strconv.Atoi(parts[1]) 32 if err != nil { 33 return false 34 } 35 36 // Validate name, shouldn't have whitespaces 37 if strings.ContainsRune(parts[0], ' ') { 38 return false 39 } 40 41 return true 42 } 43 44 var surrogates = [...][2]rune{ // [0] from, [1] to 45 {utf16.DecodeRune(0xD83C, 0xD000), utf16.DecodeRune(0xD83C, 0xDFFF)}, 46 {utf16.DecodeRune(0xD83E, 0xD000), utf16.DecodeRune(0xD83E, 0xDFFF)}, 47 {utf16.DecodeRune(0xD83F, 0xD000), utf16.DecodeRune(0xD83F, 0xDFFF)}, 48 } 49 50 func EmojiRune(r rune) bool { 51 b := r == '\u00a9' || r == '\u00ae' || 52 (r >= '\u2000' && r <= '\u3300') 53 if b { 54 return true 55 } 56 57 for _, surrogate := range surrogates { 58 if surrogate[0] <= r && r <= surrogate[1] { 59 return true 60 } 61 } 62 63 return false 64 }