github.com/influxdata/influxdb/v2@v2.7.6/tag.go (about) 1 package influxdb 2 3 import ( 4 "encoding/json" 5 "regexp" 6 "strings" 7 8 "github.com/influxdata/influxdb/v2/kit/platform/errors" 9 ) 10 11 // Operator is an Enum value of operators. 12 type Operator int 13 14 // Valid returns invalid error if the operator is invalid. 15 func (op Operator) Valid() error { 16 if op < Equal || op > NotRegexEqual { 17 return &errors.Error{ 18 Code: errors.EInvalid, 19 Msg: "Operator is invalid", 20 } 21 } 22 return nil 23 } 24 25 // operators 26 const ( 27 Equal Operator = iota 28 NotEqual 29 RegexEqual 30 NotRegexEqual 31 ) 32 33 var opStr = []string{ 34 "equal", 35 "notequal", 36 "equalregex", 37 "notequalregex", 38 } 39 40 var opStrMap = map[string]Operator{ 41 "equal": Equal, 42 "notequal": NotEqual, 43 "equalregex": RegexEqual, 44 "notequalregex": NotRegexEqual, 45 } 46 47 // ToOperator converts a string into its equivalent Operator. 48 func ToOperator(s string) (Operator, bool) { 49 s = strings.ToLower(s) 50 if op, ok := opStrMap[s]; ok { 51 return op, true 52 } 53 return -1, false 54 } 55 56 // String returns the string value of the operator. 57 func (op Operator) String() string { 58 if err := op.Valid(); err != nil { 59 return "" 60 } 61 return opStr[op] 62 } 63 64 // MarshalJSON implements json.Marshal interface. 65 func (op Operator) MarshalJSON() ([]byte, error) { 66 return json.Marshal(op.String()) 67 } 68 69 // UnmarshalJSON implements json.Unmarshaler interface. 70 func (op *Operator) UnmarshalJSON(b []byte) error { 71 var s string 72 if err := json.Unmarshal(b, &s); err != nil { 73 return &errors.Error{ 74 Code: errors.EInvalid, 75 Err: err, 76 } 77 } 78 var ok bool 79 if *op, ok = opStrMap[s]; !ok { 80 return &errors.Error{ 81 Code: errors.EInvalid, 82 Msg: "unrecognized operator", 83 } 84 } 85 return nil 86 } 87 88 // Tag is a tag key-value pair. 89 type Tag struct { 90 Key string `json:"key"` 91 Value string `json:"value"` 92 } 93 94 // NewTag generates a tag pair from a string in the format key:value. 95 func NewTag(s string) (Tag, error) { 96 var tagPair Tag 97 98 matched, err := regexp.MatchString(`^[a-zA-Z0-9_]+:[a-zA-Z0-9_]+$`, s) 99 if !matched || err != nil { 100 return tagPair, &errors.Error{ 101 Code: errors.EInvalid, 102 Msg: `tag must be in form key:value`, 103 } 104 } 105 106 tagPair.Key, tagPair.Value, _ = strings.Cut(s, ":") 107 return tagPair, nil 108 } 109 110 // Valid returns an error if the tagpair is missing fields 111 func (t Tag) Valid() error { 112 if t.Key == "" || t.Value == "" { 113 return &errors.Error{ 114 Code: errors.EInvalid, 115 Msg: "tag must contain a key and a value", 116 } 117 } 118 return nil 119 } 120 121 // QueryParam converts a Tag to a string query parameter 122 func (t *Tag) QueryParam() string { 123 return strings.Join([]string{t.Key, t.Value}, ":") 124 } 125 126 // TagRule is the struct of tag rule. 127 type TagRule struct { 128 Tag 129 Operator Operator `json:"operator"` 130 } 131 132 // Valid returns error for invalid operators. 133 func (tr TagRule) Valid() error { 134 if err := tr.Tag.Valid(); err != nil { 135 return err 136 } 137 138 return tr.Operator.Valid() 139 }