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  }