definition.go

  1package definition
  2
  3// Emoji is a data structure that holds a single emoji.
  4type Emoji struct {
  5	// Name is a name of this emoji.
  6	Name string
  7
  8	// ShortNames is a shorter representation of this emoji.
  9	ShortNames []string
 10
 11	// Unicode is an unicode representation of this emoji.
 12	Unicode []rune
 13}
 14
 15// NewEmoji returns a new Emoji.
 16func NewEmoji(name string, unicode []rune, shortNames ...string) Emoji {
 17	if len(shortNames) == 0 {
 18		panic("Emoji must have at least 1 short name.")
 19	}
 20	if len(unicode) == 0 {
 21		unicode = []rune{0xFFFD}
 22	}
 23	return Emoji{
 24		Name:       name,
 25		ShortNames: shortNames,
 26		Unicode:    unicode,
 27	}
 28}
 29
 30// IsUnicode returns true if this emoji is defined in unicode, otherwise false.
 31func (em *Emoji) IsUnicode() bool {
 32	return !(len(em.Unicode) == 1 && em.Unicode[0] == 0xFFFD)
 33}
 34
 35// Emojis is a collection of emojis.
 36type Emojis interface {
 37	// Get returns (*Emoji, true) if found mapping associated with given short name, otherwise (nil, false).
 38	Get(shortName string) (*Emoji, bool)
 39
 40	// Add adds new emojis to this collection.
 41	Add(Emojis)
 42
 43	// Clone clones this collection.
 44	Clone() Emojis
 45}
 46
 47type emojis struct {
 48	list     []Emoji
 49	m        map[string]*Emoji
 50	children []Emojis
 51}
 52
 53// NewEmojis returns a new Emojis.
 54func NewEmojis(es ...Emoji) Emojis {
 55	m := &emojis{
 56		list:     es,
 57		m:        map[string]*Emoji{},
 58		children: []Emojis{},
 59	}
 60	for i := range es {
 61		emoji := &m.list[i]
 62		for _, s := range emoji.ShortNames {
 63			m.m[s] = emoji
 64		}
 65	}
 66	return m
 67}
 68
 69func (m *emojis) Add(emojis Emojis) {
 70	m.children = append(m.children, emojis)
 71}
 72
 73func (m *emojis) Clone() Emojis {
 74	es := &emojis{
 75		list:     m.list,
 76		m:        m.m,
 77		children: make([]Emojis, len(m.children)),
 78	}
 79	copy(es.children, m.children)
 80	return es
 81}
 82
 83func (m *emojis) Get(shortName string) (*Emoji, bool) {
 84	v, ok := m.m[shortName]
 85	if ok {
 86		return v, ok
 87	}
 88
 89	for _, es := range m.children {
 90		v, ok := es.Get(shortName)
 91		if ok {
 92			return v, ok
 93		}
 94	}
 95	return nil, false
 96}
 97
 98// EmojisOption sets options for Emojis.
 99type EmojisOption func(Emojis)
100
101// WithEmojis is an EmojisOption that adds emojis to the Emojis.
102func WithEmojis(emojis ...Emoji) EmojisOption {
103	return func(m Emojis) {
104		m.Add(NewEmojis(emojis...))
105	}
106}