github.com/greenpau/go-authcrunch@v1.1.4/pkg/tagging/tag.go (about) 1 // Copyright 2022 Paul Greenberg greenpau@outlook.com 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tagging 16 17 import ( 18 "fmt" 19 ) 20 21 // Tag represents key-value tag. 22 type Tag struct { 23 Key string `json:"key,omitempty" xml:"key,omitempty" yaml:"key,omitempty"` 24 Value string `json:"value,omitempty" xml:"value,omitempty" yaml:"value,omitempty"` 25 } 26 27 // NewTag returns an instance of Tag 28 func NewTag(key, value string) *Tag { 29 return &Tag{Key: key, Value: value} 30 } 31 32 func extractStringFromInteface(i interface{}) (string, error) { 33 switch v := i.(type) { 34 case string: 35 return v, nil 36 } 37 return "", fmt.Errorf("not string") 38 } 39 40 func extractMapKeyFromInteface(k string, m map[string]interface{}) (string, error) { 41 if v, exists := m[k]; exists { 42 key, err := extractStringFromInteface(v) 43 if err != nil { 44 return "", fmt.Errorf("tag %s is malformed: %v", k, err) 45 } 46 return key, nil 47 } 48 49 return "", fmt.Errorf("tag has no %s", k) 50 } 51 52 func extractTagFromMap(m map[string]interface{}) (*Tag, error) { 53 if m == nil { 54 return nil, fmt.Errorf("tag is nil") 55 } 56 key, err := extractMapKeyFromInteface("key", m) 57 if err != nil { 58 return nil, err 59 } 60 value, err := extractMapKeyFromInteface("value", m) 61 if err != nil { 62 return nil, err 63 } 64 tag := &Tag{ 65 Key: key, 66 Value: value, 67 } 68 return tag, nil 69 } 70 71 // ExtractTags extracts tags fom a map. 72 func ExtractTags(m map[string]interface{}) ([]*Tag, error) { 73 tags := []*Tag{} 74 if m == nil { 75 return tags, fmt.Errorf("input data is nil") 76 } 77 78 extractedTags, tagExists := m["tags"] 79 if !tagExists { 80 return tags, nil 81 } 82 83 switch vs := extractedTags.(type) { 84 case []interface{}: 85 for _, extractedTag := range vs { 86 87 switch v := extractedTag.(type) { 88 case map[string]interface{}: 89 tag, err := extractTagFromMap(v) 90 if err != nil { 91 return tags, fmt.Errorf("malformed extracted tags: %v", err) 92 } 93 tags = append(tags, tag) 94 default: 95 return tags, fmt.Errorf("extracted tag is %T", extractedTag) 96 } 97 } 98 default: 99 return tags, fmt.Errorf("extracted tags are %T", vs) 100 } 101 return tags, nil 102 } 103 104 // ExtractLabels extracts labels fom a map. 105 func ExtractLabels(m map[string]interface{}) ([]string, error) { 106 labels := []string{} 107 if m == nil { 108 return labels, fmt.Errorf("input data is nil") 109 } 110 111 extractedLabels, labelsExists := m["labels"] 112 if !labelsExists { 113 return labels, nil 114 } 115 116 switch vs := extractedLabels.(type) { 117 case []interface{}: 118 for _, extractedLabel := range vs { 119 120 switch label := extractedLabel.(type) { 121 case string: 122 labels = append(labels, label) 123 default: 124 return labels, fmt.Errorf("extracted label is %T", label) 125 } 126 } 127 default: 128 return labels, fmt.Errorf("extracted labels are %T", vs) 129 } 130 return labels, nil 131 }