-
Notifications
You must be signed in to change notification settings - Fork 6
/
asset_annotations.go
110 lines (93 loc) · 2.65 KB
/
asset_annotations.go
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
/*
Copyright 2021 Adevinta
*/
package api
import (
"strings"
"time"
"github.com/adevinta/errors"
"gopkg.in/go-playground/validator.v9"
)
type AssetAnnotation struct {
AssetID string `gorm:"primary_key" json:"asset_id" validate:"required"`
Asset *Asset `json:"asset"` // This line is infered from column name "asset_id".
Key string `gorm:"primary_key" json:"key" validate:"required"`
Value string `json:"value"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
}
func (an AssetAnnotation) Validate() error {
err := validator.New().Struct(an)
if err != nil {
return errors.Validation(err)
}
return nil
}
type AssetAnnotations []*AssetAnnotation
type AssetAnnotationsMap map[string]string
type AssetAnnotationsResponse struct {
Annotations AssetAnnotationsMap `json:"annotations"`
}
func (ans AssetAnnotations) ToMap() AssetAnnotationsMap {
m := AssetAnnotationsMap{}
for _, an := range ans {
m[an.Key] = an.Value
}
return m
}
func (anm AssetAnnotationsMap) ToModel() AssetAnnotations {
annotations := AssetAnnotations{}
for k, v := range anm {
annotations = append(annotations, &AssetAnnotation{
Key: k,
Value: v,
})
}
return annotations
}
func (ans AssetAnnotations) ToResponse() AssetAnnotationsResponse {
return AssetAnnotationsResponse{Annotations: ans.ToMap()}
}
// Matches returns true if the current object exactly matches (both key and value)
// the asset annotation map passed as parameter. If a prefix is specified, only
// the keys matching the prefix are evaluated
func (ans AssetAnnotationsMap) Matches(annotations AssetAnnotationsMap, prefix string) bool {
// Search a into b
for k, v := range ans {
if strings.HasPrefix(k, prefix) {
if value, ok := annotations[k]; !ok || v != value {
return false
}
}
}
// Search b into a
for k, v := range annotations {
if strings.HasPrefix(k, prefix) {
if value, ok := ans[k]; !ok || v != value {
return false
}
}
}
return true
}
// Merge takes an annotation map as input and merges it into the "base" annotation
// map, giving priority to the values of the former.
// If a prefix is specified, elements from the "base" map whose keys match the
// prefix are discarded
func (ans AssetAnnotationsMap) Merge(annotations AssetAnnotationsMap, prefix string) AssetAnnotationsMap {
// Make a copy of the input annotations
output := AssetAnnotationsMap{}
for k, v := range annotations {
output[k] = v
}
for k, v := range ans {
if _, ok := output[k]; ok {
continue
} else if !ok && prefix == "" {
output[k] = v
} else if !ok && prefix != "" && !strings.HasPrefix(k, prefix) {
output[k] = v
}
}
return output
}