mirror of https://github.com/status-im/gomoji.git
82 lines
1.6 KiB
Go
82 lines
1.6 KiB
Go
package gomoji
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
type (
|
|
// Provider is an emoji provider.
|
|
Provider interface {
|
|
AllEmojis(ctx context.Context) ([]Emoji, error)
|
|
}
|
|
|
|
// Service is a service to work with emojis using a provider. The service methods are concurrent safe.
|
|
Service struct {
|
|
p Provider
|
|
emojiMap map[rune]Emoji
|
|
mu sync.RWMutex
|
|
}
|
|
)
|
|
|
|
// NewService creates a new instance of service.
|
|
func NewService(p Provider) *Service {
|
|
return &Service{
|
|
p: p,
|
|
}
|
|
}
|
|
|
|
func (s *Service) initEmojiMap(ctx context.Context) error {
|
|
if s.emojiMap != nil {
|
|
return nil
|
|
}
|
|
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
emojis, err := s.p.AllEmojis(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("get all emojis: %w", err)
|
|
}
|
|
|
|
s.emojiMap = make(map[rune]Emoji, len(emojis))
|
|
for _, e := range emojis {
|
|
s.emojiMap[[]rune(e.Character)[0]] = e
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ContainsEmoji checks whether given string contains emoji or not. It takes emoji data from provider.
|
|
func (s *Service) ContainsEmoji(ctx context.Context, str string) (bool, error) {
|
|
err := s.initEmojiMap(ctx)
|
|
if err != nil {
|
|
return false, fmt.Errorf("fill emoji map: %w", err)
|
|
}
|
|
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
for _, r := range str {
|
|
if _, ok := s.emojiMap[r]; ok {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
// AllEmojis gets all emojis from provider.
|
|
func (s *Service) AllEmojis(ctx context.Context) ([]Emoji, error) {
|
|
err := s.initEmojiMap(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("fill emoji map: %w", err)
|
|
}
|
|
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
return emojiMapToSlice(s.emojiMap), nil
|
|
}
|