1package bug
2
3import (
4 "crypto/sha256"
5 "fmt"
6 "image/color"
7 "strings"
8
9 fcolor "github.com/fatih/color"
10
11 "github.com/MichaelMure/git-bug/util/text"
12)
13
14type Label string
15
16func (l Label) String() string {
17 return string(l)
18}
19
20// RGBA from a Label computed in a deterministic way
21func (l Label) Color() LabelColor {
22 // colors from: https://material-ui.com/style/color/
23 colors := []LabelColor{
24 {R: 244, G: 67, B: 54, A: 255}, // red
25 {R: 233, G: 30, B: 99, A: 255}, // pink
26 {R: 156, G: 39, B: 176, A: 255}, // purple
27 {R: 103, G: 58, B: 183, A: 255}, // deepPurple
28 {R: 63, G: 81, B: 181, A: 255}, // indigo
29 {R: 33, G: 150, B: 243, A: 255}, // blue
30 {R: 3, G: 169, B: 244, A: 255}, // lightBlue
31 {R: 0, G: 188, B: 212, A: 255}, // cyan
32 {R: 0, G: 150, B: 136, A: 255}, // teal
33 {R: 76, G: 175, B: 80, A: 255}, // green
34 {R: 139, G: 195, B: 74, A: 255}, // lightGreen
35 {R: 205, G: 220, B: 57, A: 255}, // lime
36 {R: 255, G: 235, B: 59, A: 255}, // yellow
37 {R: 255, G: 193, B: 7, A: 255}, // amber
38 {R: 255, G: 152, B: 0, A: 255}, // orange
39 {R: 255, G: 87, B: 34, A: 255}, // deepOrange
40 {R: 121, G: 85, B: 72, A: 255}, // brown
41 {R: 158, G: 158, B: 158, A: 255}, // grey
42 {R: 96, G: 125, B: 139, A: 255}, // blueGrey
43 }
44
45 id := 0
46 hash := sha256.Sum256([]byte(l))
47 for _, char := range hash {
48 id = (id + int(char)) % len(colors)
49 }
50
51 return colors[id]
52}
53
54func (l Label) Validate() error {
55 str := string(l)
56
57 if text.Empty(str) {
58 return fmt.Errorf("empty")
59 }
60
61 if strings.Contains(str, "\n") {
62 return fmt.Errorf("should be a single line")
63 }
64
65 if !text.Safe(str) {
66 return fmt.Errorf("not fully printable")
67 }
68
69 return nil
70}
71
72type LabelColor color.RGBA
73
74func (lc LabelColor) RGBA() color.RGBA {
75 return color.RGBA(lc)
76}
77
78func (lc LabelColor) Term256() Term256 {
79 red := Term256(lc.R) * 6 / 256
80 green := Term256(lc.G) * 6 / 256
81 blue := Term256(lc.B) * 6 / 256
82
83 return red*36 + green*6 + blue + 16
84}
85
86type Term256 int
87
88func (t Term256) Escape() string {
89 if fcolor.NoColor {
90 return ""
91 }
92 return fmt.Sprintf("\x1b[38;5;%dm", t)
93}
94
95func (t Term256) Unescape() string {
96 if fcolor.NoColor {
97 return ""
98 }
99 return "\x1b[0m"
100}