github.com/diamondburned/arikawa/v2@v2.1.0/state/store/defaultstore/emoji.go (about) 1 package defaultstore 2 3 import ( 4 "sync" 5 6 "github.com/diamondburned/arikawa/v2/discord" 7 "github.com/diamondburned/arikawa/v2/internal/moreatomic" 8 "github.com/diamondburned/arikawa/v2/state/store" 9 ) 10 11 type Emoji struct { 12 guilds moreatomic.Map 13 } 14 15 type emojis struct { 16 mut sync.Mutex 17 emojis []discord.Emoji 18 } 19 20 var _ store.EmojiStore = (*Emoji)(nil) 21 22 func NewEmoji() *Emoji { 23 return &Emoji{ 24 guilds: *moreatomic.NewMap(func() interface{} { 25 return &emojis{ 26 emojis: []discord.Emoji{}, 27 } 28 }), 29 } 30 } 31 32 func (s *Emoji) Reset() error { 33 s.guilds.Reset() 34 return nil 35 } 36 37 func (s *Emoji) Emoji(guildID discord.GuildID, emojiID discord.EmojiID) (*discord.Emoji, error) { 38 iv, ok := s.guilds.Load(guildID) 39 if !ok { 40 return nil, store.ErrNotFound 41 } 42 43 es := iv.(*emojis) 44 45 es.mut.Lock() 46 defer es.mut.Unlock() 47 48 for _, emoji := range es.emojis { 49 if emoji.ID == emojiID { 50 // Emoji is an implicit copy made by range, so we could do this 51 // safely. 52 return &emoji, nil 53 } 54 } 55 56 return nil, store.ErrNotFound 57 } 58 59 func (s *Emoji) Emojis(guildID discord.GuildID) ([]discord.Emoji, error) { 60 iv, ok := s.guilds.Load(guildID) 61 if !ok { 62 return nil, store.ErrNotFound 63 } 64 65 es := iv.(*emojis) 66 67 es.mut.Lock() 68 defer es.mut.Unlock() 69 70 // We're never modifying the slice internals ourselves, so this is fine. 71 return es.emojis, nil 72 } 73 74 func (s *Emoji) EmojiSet(guildID discord.GuildID, allEmojis []discord.Emoji) error { 75 iv, _ := s.guilds.LoadOrStore(guildID) 76 77 es := iv.(*emojis) 78 79 es.mut.Lock() 80 es.emojis = allEmojis 81 es.mut.Unlock() 82 83 return nil 84 }