server/types/tag.go

84 lines
1.7 KiB
Go

/**
* file: types/tag.go
* author: Theo Technicguy
* license: Apache 2.0
*
* Tag type and functions
*/
package types
import (
"crypto/sha1"
"encoding/binary"
"errors"
)
const (
colorBase = 0xff
colorRage = colorBase*colorBase*colorBase + 1
)
var (
ErrTagNameEmpty = errors.New("tag name is empty")
ErrTagHasColor = errors.New("tag has valid color")
ErrTagInvalidCollor = errors.New("tag has invalid color")
)
// A Tag is a simple structure used to categorize products.
// Tag names are unique. Tag colors are base 10 RGB notation.
type Tag struct {
Id uint `json:"id"`
Name string `json:"name"`
Color uint `json:"color"`
}
// GenerateColor generates a random tag color using the tag's
// name's SHA1.
func (t *Tag) GenerateColor() error {
if t.Name == "" {
return ErrTagNameEmpty
}
if t.ValidColor() {
return ErrTagHasColor
}
hash := sha1.Sum([]byte(t.Name))
t.Color = uint(binary.BigEndian.Uint64(hash[:])) % colorRage
return nil
}
// RGB converts the base 10 RGB color in an array of color values.
func (t *Tag) RGB() ([]uint, error) {
if !t.ValidColor() {
return nil, ErrTagInvalidCollor
}
c := t.Color
colors := []uint{}
for c > 0 {
colors = append(colors, c%colorBase)
c = c / colorBase
}
return colors, nil
}
// ValidColor verifies that the tag's color is valid.
func (t *Tag) ValidColor() bool {
return t.Color < colorRage
}
// ValidName verifies that the tag has a name.
// Uniqueness verification is the data source's job.
func (t *Tag) ValidName() bool {
return t.Name != ""
}
// Valid verifies that the tag is valid.
// A valid tag has a valid color and a name.
func (t *Tag) Valid() bool {
return t.ValidColor() && t.ValidName()
}