1package bug
2
3import (
4 "fmt"
5 "io"
6 "strings"
7
8 "github.com/MichaelMure/git-bug/util/text"
9)
10
11type Color struct {
12 red uint8
13 green uint8
14 blue uint8
15}
16
17type Label string
18
19func (l Label) String() string {
20 return string(l)
21}
22
23func (l Label) Color() Color {
24 label := string(l)
25 id := 0
26
27 // colors from: https://material-ui.com/style/color/
28 colors := []Color{
29 Color{red: 244, green: 67, blue: 54}, // red
30 Color{red: 233, green: 30, blue: 99}, // pink
31 Color{red: 156, green: 39, blue: 176}, // purple
32 Color{red: 103, green: 58, blue: 183}, // deepPurple
33 Color{red: 63, green: 81, blue: 181}, // indigo
34 Color{red: 33, green: 150, blue: 243}, // blue
35 Color{red: 3, green: 169, blue: 244}, // lightBlue
36 Color{red: 0, green: 188, blue: 212}, // cyan
37 Color{red: 0, green: 150, blue: 136}, // teal
38 Color{red: 76, green: 175, blue: 80}, // green
39 Color{red: 139, green: 195, blue: 74}, // lightGreen
40 Color{red: 205, green: 220, blue: 57}, // lime
41 Color{red: 255, green: 235, blue: 59}, // yellow
42 Color{red: 255, green: 193, blue: 7}, // amber
43 Color{red: 255, green: 152, blue: 0}, // orange
44 Color{red: 255, green: 87, blue: 34}, // deepOrange
45 Color{red: 121, green: 85, blue: 72}, // brown
46 Color{red: 158, green: 158, blue: 158}, // grey
47 Color{red: 96, green: 125, blue: 139}, // blueGrey
48 }
49
50 for pos, char := range label {
51 id = (pos + id + int(char)) % len(colors)
52 }
53
54 return colors[id]
55}
56
57// UnmarshalGQL implements the graphql.Unmarshaler interface
58func (l *Label) UnmarshalGQL(v interface{}) error {
59 _, ok := v.(string)
60 if !ok {
61 return fmt.Errorf("labels must be strings")
62 }
63
64 *l = v.(Label)
65
66 return nil
67}
68
69// MarshalGQL implements the graphql.Marshaler interface
70func (l Label) MarshalGQL(w io.Writer) {
71 _, _ = w.Write([]byte(`"` + l.String() + `"`))
72}
73
74func (l Label) Validate() error {
75 str := string(l)
76
77 if text.Empty(str) {
78 return fmt.Errorf("empty")
79 }
80
81 if strings.Contains(str, "\n") {
82 return fmt.Errorf("should be a single line")
83 }
84
85 if !text.Safe(str) {
86 return fmt.Errorf("not fully printable")
87 }
88
89 return nil
90}