-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathlabel.go
More file actions
146 lines (108 loc) · 2.72 KB
/
Copy pathlabel.go
File metadata and controls
146 lines (108 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2013-2016 lessgo Author, All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"errors"
"fmt"
"regexp"
"sync"
)
var (
label_name_re2 = regexp.MustCompile("^[a-z]{1}[a-z0-9-._/]{0,99}$")
label_mu sync.RWMutex
labelErrNameEmpty = errors.New("label name cannot be empty")
labelErrNameLength = errors.New("length of the label name must be less than 100")
labelErrNameInvalid = errors.New("invalid label name")
)
// Labels are name value pairs that may be used to scope and select individual items.
type Labels []Label
// Label is a name value . It implements Labels
type Label struct {
Name string `json:"name" toml:"name"`
Value string `json:"value,omitempty" toml:"value,omitempty"`
}
// Set create or update the label entry for "name" to "value".
func (ls *Labels) Set(name string, value interface{}) error {
label_mu.Lock()
defer label_mu.Unlock()
if len(name) < 1 {
return labelErrNameEmpty
}
if len(name) > 100 {
return labelErrNameLength
}
if !label_name_re2.MatchString(name) {
return labelErrNameInvalid
}
svalue := fmt.Sprintf("%v", value)
for i, prev := range *ls {
if prev.Name == name {
if prev.Value != svalue {
(*ls)[i].Value = svalue
}
return nil
}
}
*ls = append(*ls, Label{
Name: name,
Value: svalue,
})
return nil
}
// Get fetch the label entry "value" (if any) for "name".
func (ls Labels) Get(name string) (Bytex, bool) {
label_mu.RLock()
defer label_mu.RUnlock()
for _, prev := range ls {
if prev.Name == name {
return Bytex(prev.Value), true
}
}
return Bytex(""), false
}
// Del remove the label entry (if any) for "name".
func (ls *Labels) Del(name string) {
label_mu.Lock()
defer label_mu.Unlock()
for i, prev := range *ls {
if prev.Name == name {
*ls = append((*ls)[:i], (*ls)[i+1:]...)
break
}
}
}
func (ls *Labels) Equal(items Labels) bool {
label_mu.RLock()
defer label_mu.RUnlock()
if len(*ls) != len(items) {
return false
}
for _, v := range *ls {
hit := false
for _, v2 := range items {
if v.Name != v2.Name {
continue
}
if v.Value != v2.Value {
return false
}
hit = true
break
}
if !hit {
return false
}
}
return true
}